劍指offer-重建二叉樹
阿新 • • 發佈:2019-02-17
題目:
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都
不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。
解題:仔細觀察重建二叉樹,前序遍歷和中序遍歷規律,前序遍歷是存放根節點,中序就是以此節點做切分左右子樹!遞迴是樹本質,遞迴這個時候寫出來的程式碼特美!
struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin) { int vin_size = vin.size(); if (vin_size == 0) return NULL; int val = pre[0];//root or subroot TreeNode* node = new TreeNode(val); int p = 0; for (; p<vin_size; p++){ if (vin[p] == val)//root positon break; } //直接初始化,注意容器初始化另外一個容器最好採用偏移位置,不要採用陣列[]索引形式傳入地址,容器的最後一個地址是end是不給陣列形式索引的! vector<int> vin_left(vin.begin(), vin.begin()+p),\ vin_right(vin.begin() + p + 1, vin.begin()+vin_size),\ pre_left(pre.begin() + 1, pre.begin()+p+1),\ pre_right(pre.begin()+p+1, pre.begin()+vin_size); //或者採用迴圈 /*for (int i = 0; i<vin_size; i++){ if (i<p){ vin_left.push_back(vin[i]); pre_left.push_back(pre[i + 1]); } else if (i>p){ vin_right.push_back(vin[i]); pre_right.push_back(pre[i]); } }*/ node->left = reConstructBinaryTree(pre_left, vin_left);//先構造左邊 node->right = reConstructBinaryTree(pre_right, vin_right);//接著右邊 return node; } void printf_middle_order(TreeNode* boot) { if (boot != NULL) { printf_middle_order(boot->left); printf("%d ",boot->val); printf_middle_order(boot->right); } } void printf_pre_order(TreeNode* boot) { if (boot != NULL) { printf("%d ", boot->val); printf_middle_order(boot->left); printf_middle_order(boot->right); } } int main() { int pre_shuzu[8] = { 1, 2, 4, 7, 3, 5, 6, 8 }; int vin_shuzu[8] = { 4, 7, 2, 1, 5, 3, 8, 6 }; vector<int> pre(&pre_shuzu[0],&pre_shuzu[8]);//注意vector結束是要陣列的最後一個元素的下一個地址 vector<int> vin(&vin_shuzu[0], &vin_shuzu[8]); TreeNode* tree_boot = reConstructBinaryTree(pre,vin); printf_middle_order(tree_boot); while (true) { } return 0; }