題目內容:
我們知道如何按照三種深度優先次序來周游一棵二叉樹,來得到中根序列、前根序列和后根序列。反過來,如果給定二叉樹的中根序列和后根序列,或者給定中根序列和前根序列,可以重建一二叉樹。本題輸入一棵二叉樹的中根序列和后根序列,要求在內存中重建二叉樹,最后輸出這棵二叉樹的前根序列。
用不同的整數來唯一標識二叉樹的每一個結點,下面的二叉樹
中根序列是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 }