1 // 類定義代碼 2 struct TreeNode 3 { 4 char val; 5 TreeNode* left; 6 TreeNode* right; 7 TreeNode(char x) : val(x), left(NULL), right(NULL) {} 8 }; 9 int main() 10 { 11 char* pre = "ACDEBF"; 12 char* vin = "DCEABF"; 13 char* post = "DECFBA"; 14 return 0; 15 }
1. 前序遍歷和中序遍歷還原二叉樹
算法思想:描述如下:
- 根據 前序遍歷 結果,第一個元素為二叉樹的根節點;
- 觀察 中序遍歷 結果,根節點左側的為左子樹,若左子樹根節點前(后)再無任何元素,則左(右)子樹的左分支為空;根節點右側的為右子樹,若右子樹根節點前(后)再無任何元素,則左(右)子樹的左分支為空;
- 通過以上遞歸過程。先找到當前樹的根節點,然后划分為左右子樹,再進入左子樹重復上面的過程,最后再進入右子樹重復上面的過程,最終還原一棵樹。
遞歸代碼:
1 TreeNode* BinaryTreeFromOrderings(char* pre, char* vin, int length) 2 { 3 if( length == 0 ) return NULL; 4 5 int rootIndex = 0; 6 // 尋找當前根節點,記錄子樹元素個數 7 for(; rootIndex < length; rootIndex ++) 8 if( vin[rootIndex] == pre[0] ) break; 9 10 TreeNode* tree = new TreeNode( vin[rootIndex] ); 11 // 返回當前左子樹 12 tree ->left = BinaryTreeFromOrderings(pre + 1, vin, rootIndex ); 13 // 返回當前右子樹 14 tree ->right = BinaryTreeFromOrderings(pre + rootIndex + 1, vin + rootIndex + 1, length - (rootIndex + 1)); 15 16 return tree; 17 }
2. 中序遍歷和后序遍歷還原二叉樹
算法思想:描述如下:
- 根據后序遍歷結果,最后一個元素為二叉樹的根節點;
- 觀察中序遍歷結果,其中根節點左側為左子樹,若左子樹根節點前(后)再無任何元素,則左(右)子樹的左分支為空;其中根節點右側為右子樹,若右子樹根節點前(后)再無任何元素,則左(右)子樹的左分支為空;
- 上面描述的過程是遞歸的。現根據后續遍歷結果找根節點,根節點左側為左子樹,右側為右子樹,再進入左子樹重復上面的過程,最后進入右子樹重復上面的過程,最終還原一棵樹。
遞歸代碼:
TreeNode* BinaryTreeFromPostings(char* vin, char* post, int length) { if( length == 0 ) return NULL; int rootIndex = 0; // 尋找當前根節點,記錄子樹元素個數 for(; rootIndex < length; rootIndex ++) if( vin[rootIndex] == post[length - 1]) break; TreeNode* tree = new TreeNode( vin[rootIndex] ); // 返回當前右子樹 tree ->right = BinaryTreeFromPostings(vin + rootIndex + 1, post + rootIndex, length - (rootIndex + 1) ); // 返回當前左子樹 tree ->left = BinaryTreeFromPostings(vin, post, rootIndex ); return tree; }
3. 前序遍歷和后序遍歷還原二叉樹
已知前序和中序,后序和中序遍歷序列之后,可以唯一確定一棵二叉樹。但是,只知道前序和后序遍歷序列,是無法分辨哪個結點是左子樹或右子樹。