题目内容:
我们知道如何按照三种深度优先次序来周游一棵二叉树,来得到中根序列、前根序列和后根序列。反过来,如果给定二叉树的中根序列和后根序列,或者给定中根序列和前根序列,可以重建一二叉树。本题输入一棵二叉树的中根序列和后根序列,要求在内存中重建二叉树,最后输出这棵二叉树的前根序列。
用不同的整数来唯一标识二叉树的每一个结点,下面的二叉树
中根序列是9 5 32 67
后根序列9 32 67 5
前根序列5 9 67 32
输入格式:
两行。第一行是二叉树的中根序列,第二行是后根序列。每个数字表示的结点之间用空格隔开。结点数字范围0~65535。暂不必考虑不合理的输入数据。
输出格式:
一行。由输入中的中根序列和后根序列重建的二叉树的前根序列。每个数字表示的结点之间用空格隔开。
【题解】
后根序列的最后一个元素即为二叉树的树根root。root将中根序列分为两部分,左半边是左子树的中根序列,而右半边则是右部分的中根序列。同时后根序列依照左子树和右子树节点数也可以被分为左子树的后根序列和右子树的后根序列。于是便可依此递归地按左右子树的后根、中根序列重建子树,最终重建二叉树。
【代码】
1 #include <iostream> 2 using namespace std; 3 /*build BT from its inorder and postorder*/ 4 5 6 constexpr int MAXN = 65540; 7 int postorder[MAXN], inorder[MAXN]; 8 9 struct btn 10 { 11 int data; 12 btn *left; 13 btn *right; 14 }; 15 16 btn *build_tree(int io1, int io2, int po1, int po2) 17 { 18 /*io1, io2 are the begining and ending points of inorder sequence respectively*/ 19 /*po1, po2 are the begining and ending points of postorder sequence respectively*/ 20 int i = 0, ion = io2 - io1 + 1; 21 btn* root = new btn; 22 root->data = postorder[po2]; 23 root->left = NULL; 24 root->right = NULL; 25 for (i = 0; i < ion; i++) { 26 if (root->data == inorder[io1 + i])break; 27 } 28 if (i > 0) root->left = build_tree(io1, io1 + i - 1, po1, po1 + i - 1); 29 if (io1 + i < io2) root->right = build_tree(io1 + i + 1, io2, po1 + i, po2 - 1); 30 return root; 31 } 32 33 void preorder(btn *root, int vnum, int &count) 34 { 35 if (root != NULL) { 36 cout << root->data; 37 if (count < vnum - 1) { 38 cout << " "; 39 count++; 40 preorder(root->left, vnum, count); 41 preorder(root->right, vnum, count); 42 } 43 else cout << endl; 44 } 45 } 46 47 void deletetree(btn *root) 48 { 49 if (root != NULL) { 50 delete(root->left); 51 delete(root->right); 52 delete root; 53 root = NULL; 54 } 55 } 56 57 int main() 58 { 59 int c = 0, i = 0, vnum = 0; 60 while (cin >> inorder[i++]) { 61 if (cin.get() != ' ')break; 62 /*Although cin will skip the blank space, the cursor stays at the blank after cin reads a number,thus cin.get() can fetch the 63 blank space.*/ 64 } 65 66 vnum = i; 67 i = 0; 68 while (cin >> postorder[i++]) { 69 if (cin.get() != ' ')break; 70 } 71 btn *root = build_tree(0, i - 1, 0, i - 1); 72 preorder(root, vnum, c); 73 deletetree(root); 74 return 0; 75 }