題目描述
有一棵二叉樹,每個節點由一個大寫字母標識(最多26個節點)。現有兩組字母,分別表示前序遍歷(父節點->左孩子->右孩子)和中序遍歷(左孩子->父節點->右孩子)的結果,請你輸出后序遍歷(左孩子->右孩子->父節點)的結果。
解答要求時間限制:1000ms, 內存限制:100MB
輸入
每個輸入文件包含兩串字母,各占一行。(每串只包含大寫字母)
第一行字母表示前序遍歷結果,第二行字母表示中序遍歷結果。
輸出
輸出僅一行,表示后序遍歷的結果,結尾換行。
樣例
提示
前序遍歷:根—>左孩子—>右孩子
中序遍歷:左孩子—>根—>右孩子
后序遍歷:左孩子—>右孩子—>根
所謂的前中后指的是根的位置,而左右孩子順序是不變的。
例如已知前序遍歷是DBACEGF,中序遍歷是ABCDEFG,那么由前序遍歷先根,可知道D是樹的根,再看在中序遍歷中D左邊是ABC,所以可知道ABC一定在D的左子樹上,而EFG在D的右子樹上。
那么前序遍歷為BAC,中序遍歷為ABC,所以B為根,在中序遍歷中A在B的左邊,C在B的右邊,所以A為B的左孩子,C為B的右孩子。
思路:先從先序遍歷中找到根節點,然后從中序遍歷中找到左子樹和右子樹,遞歸,構建二叉樹,最后再進行后序遍歷。
// we have defined the necessary header files here for this problem. // If additional header files are needed in your program, please import here. #include<iostream> using namespace std; #include<string.h> struct TreeNode//定義二叉樹 { TreeNode* left; TreeNode* right; char val; TreeNode(char v):val(v),left(NULL),right(NULL){} }; TreeNode*constructTree(string Preorder,string Inorder)//根據中序和先序構建二叉樹 { if(Preorder.size()==0) { return NULL; } char midval = Preorder[0]; TreeNode*root = new TreeNode(midval); if(Preorder.size() == 1) { return root; } int midx = 0; for(;midx<Preorder.size();midx++) { if(midval == Inorder[midx]) { break; } } string pre_left = Preorder.substr(1,midx); string pre_right = Preorder.substr(midx+1); string In_left = Inorder.substr(0,midx); string In_right = Inorder.substr(midx+1); root->left = constructTree(pre_left,In_left); root->right = constructTree(pre_right,In_right); return root; } void lastorder(TreeNode*Node)//輸出后序遍歷 { if(Node == NULL) { return; } lastorder(Node->left); lastorder(Node->right); cout<<Node->val; } int main() { // please define the C input here. For example: int n; scanf("%d",&n); // please finish the function body here. // please define the C output here. For example: printf("%d\n",a); string pre,in; cin>>pre>>in; TreeNode*root = constructTree(pre,in); lastorder(root); return 0; }