1. 程式人生 > >二叉樹重建(c++)

二叉樹重建(c++)

題目描述(劍指offer)

輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。  
  1 #include <iostream>
  2 #include <vector>
  3 using namespace std;
  4 
  5  // Definition for binary tree
  6 struct TreeNode {
7 int val; 8 TreeNode *left; 9 TreeNode *right; 10 TreeNode(int x) : val(x), left(NULL), right(NULL) {} 11 12 }; 13 /* 先序遍歷第一個位置肯定是根節點node, 14 中序遍歷的根節點位置在中間p,在p左邊的肯定是node的左子樹的中序陣列,p右邊的肯定是node的右子樹的中序陣列 15 另一方面,先序遍歷的第二個位置到p,也是node左子樹的先序子陣列,剩下p右邊的就是node的右子樹的先序子陣列 16 把四個陣列找出來,分左右遞迴呼叫即可
17 */ 18 19 class Solution 20 { 21 public: 22 struct TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin) 23 { 24 int in_size = vin.size();//獲取序列的長度 25 if (in_size == 0) 26 return NULL; 27 28 //分別儲存先序序列的左子樹,先序序列的右子樹,中序序列的左子樹,中序序列的右子樹
29 vector<int>pre_left, pre_right, in_left, in_right; 30 31 int val = pre[0];//先序遍歷第一個位置是根節點node,取其值 32 //新建一個樹結點,並傳入結點值 33 TreeNode* node = new TreeNode(val); 34 35 //p用於儲存中序序列中根節點的位置 36 int p = 0; 37 for (p; p < in_size; ++p) 38 { 39 if (vin[p] == val) 40 break;//找到即跳出for迴圈 41 } 42 43 for (int i = 0; i < in_size; ++i) 44 { 45 if (i < p) 46 { 47 //建立中序序列的左子樹和前序序列的左子樹 48 in_left.push_back(vin[i]); 49 pre_left.push_back(pre[i + 1]);//前序第一個為根節點,+1從下一個開始記錄 50 } 51 else if(i>p) 52 { 53 //建立中序序列的右子樹和前序序列的右子樹 54 in_right.push_back(vin[i]); 55 pre_right.push_back(pre[i]); 56 } 57 } 58 59 //取出前序和中序遍歷根節點左邊和右邊的子樹 60 //遞迴,再對其進行上述所有步驟,即再區分子樹的左、右子子數,直到葉節點 61 node->left = reConstructBinaryTree(pre_left, in_left); 62 node->right = reConstructBinaryTree(pre_right, in_right); 63 64 return node; 65 } 66 67 }; 68 69 //test=====後序遞迴遍歷二叉樹 70 void Posorder(TreeNode* &T) 71 { 72 if (T)//當結點不為空的時候執行 73 { 74 //左右中 75 Posorder(T->left); 76 Posorder(T->right); 77 cout << T->val; 78 79 } 80 else 81 { 82 //cout << " "; 83 T = NULL; 84 } 85 } 86 87 int main() 88 { 89 vector<int>pre{1,2,4,7,3,5,6,8}; 90 vector<int>vin{4,7,2,1,5,3,8,6}; 91 92 Solution T; 93 TreeNode* node=T.reConstructBinaryTree(pre, vin); 94 95 //測試---輸出後續遍歷 96 cout << "後續遍歷為:" << endl; 97 Posorder(node); 98 cout << endl; 99 100 system("pause"); 101 }

測試結果: