1. 程式人生 > >劍指Offer——重建二叉樹

劍指Offer——重建二叉樹

urn return 重復 col 分割 init 樹的遍歷 ++ fin

題目描述:

輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重復的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。


分析:

二叉樹前序遍歷的第一個值是根節點的值,從中序遍歷中找到該值則可以從中序遍歷中分開左子樹和右子樹。繼續對左子樹和右子樹的遍歷序列進行查找分割,遞歸該步驟就可以得到整棵二叉樹。


代碼:

 1 /**
 2  * Definition for binary tree
 3  * struct TreeNode {
 4  *     int val;
5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 int Search(vector<int> &vin, int vinLeft, int vinRight, int key) { 13 int i = (vinLeft + vinRight) >> 1; 14 int
j = i + 1; 15 while(i >= vinLeft && j <= vinRight) { // 從中間往兩邊查找比較快能找到要找的值的位置 16 if(vin[i] == key) return i; 17 if(vin[j] == key) return j; 18 i--; 19 j++; 20 } 21 return vinLeft; 22 } 23 TreeNode* myReConstructBinaryTree(vector<int
> &pre, int preLeft, int preRight, vector<int> &vin, int vinLeft, int vinRight) { 24 if(preLeft > preRight || vinLeft > vinRight) return NULL; 25 TreeNode* t = new TreeNode(pre[preLeft]); 26 int k = Search(vin, vinLeft, vinRight, pre[preLeft]); // vin中k位置前的肯定是左子樹的各個節點的值,k位置後肯定是右子樹的各個節點的值 27 t->left = myReConstructBinaryTree(pre, preLeft + 1, preLeft + k - vinLeft, vin, vinLeft, k - 1); 28 t->right = myReConstructBinaryTree(pre, preLeft + k - vinLeft + 1, preRight, vin, k + 1, vinRight); 29 return t; 30 } 31 TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin) { 32 int Size = pre.size(); 33 return myReConstructBinaryTree(pre, 0, Size - 1, vin, 0, Size - 1); 34 } 35 };

劍指Offer——重建二叉樹