劍指offer------重建二叉樹
阿新 • • 發佈:2018-12-12
題目
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。
思路
通常樹有如下幾種遍歷方式:
- 前序遍歷:先訪問根結點,再訪問左子結點,最後訪問右子結點。
- 中序遍歷:先訪問左子結點,再訪問根結點,最後訪問右子結點。
- 後序遍歷:先訪問左子結點,再訪問右子結點,最後訪問根結點。
本題為前序遍歷和中序遍歷,最少需要兩種遍歷方式,才能重建二叉樹。
前序遍歷序列中,第一個數字總是樹的根結點的值。在中序遍歷序列中,根結點的值在序列的中間,左子樹的結點的值位於根結點的值的左邊,而右子樹的結點的值位於根結點的值的右邊。剩下的我們可以遞迴來實現,具體如圖:
程式碼:
struct TreeNode { int val; TreeNode *left; TreeNode *right; } class Solution { public: TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) { if(pre.size()==0||vin.size()==0) return NULL; //依次是前序遍歷左子樹,前序遍歷右子樹,中序遍歷左子樹,中序遍歷右子樹 vector<int> left_pre, right_pre, left_vin, right_vin; //前序遍歷第一個節點一定為根節點 TreeNode* head = new TreeNode(); head-val=pre[0]; //找到中序遍歷的根節點 int root = 0; //遍歷找到中序遍歷根節點索引值 for(int i=0;i<pre.size();i++) { if(pre[0]==vin[i]) { root=i; break; } } //利用中序遍歷的根節點,對二叉樹節點進行歸併 for(int i=0;i<root;i++) { left_vin.push_back(vin[i]); left-pre.push_back(pre[i+1]); } for(int i=root+1;i<pre.size();i++) { right_vin.push_back(vin[i]); right_pre.push_back(pre[i]); } //遞迴,再對其進行上述所有步驟,即再區分子樹的左、右子子數,直到葉節點 head->left = reConstructBinaryTree(left_pre, left_vin); head->right = reConstructBinaryTree(right_pre, right_vin); return head; } };