leetcode 106. 从中序与后序遍历序列构造二叉树 c语言递归解法
如題:
根據一棵樹的中序遍歷與后序遍歷構造二叉樹。 注意: 你可以假設樹中沒有重復的元素。例如,給出 中序遍歷 inorder =?[9,3,15,20,7] 后序遍歷 postorder = [9,15,7,20,3] 返回如下的二叉樹:3/ \9 20/ \15 7這道題明顯是有套路的,如果你還不會,說明你是第一次遇到,還好現在遇到,省的筆試的時候現場尷尬。可以根據中序遍歷和后序遍歷得到的序列遞歸求解子樹。首先,我們知道,后序遍歷得到的序列從后往前依次是原二叉樹的根節點,根節點右子樹的根節點.....,右子樹的左子樹的根節點。如果不理解的話, 沒關系,待會看幅圖就理解了。其次呢,我們可以知道,中序遍歷中,根節點的位置是在中間的。這樣,第一次,我們從后序遍歷中找到根節點的值val,然后在中序遍歷中找到val所屬下標i,這時候得到val的左子樹范圍為【0, i-1】,右子樹范圍為【i+1, end】。緊接著,我們繼續在相應的子樹范圍內找根節點,誰的根節點,分別是右子樹的根節點和左子樹的根節點,找到后,和val組合即可。看下圖:
從圖中的后序遍歷從后往前觀察,20是根節點,18是20右子樹的根節點,7是18右子樹的根節點。8是18的左子樹根節點。像這樣每次遞歸的查找根節點,然后組合即可。初始遍歷的時候,中序遍歷范圍為0~InEnd,找到第一次后,劃分為左子樹范圍【0, i-1】,右子樹范圍【i+1, end】。每次遍歷從后序遍歷數列中取根節點前,先判斷其實范圍start是否大于end,如果是的話,說明已經到底了,這時候遞歸即可返回。這一點結合代碼可以看出:
struct TreeNode *findSubTree(int* inorder, int* postorder, int *postEnd, int inStart, int inEnd) {int val, i;struct TreeNode *root, *left, *right;//首先判斷是否溢出了,溢出則返回。if (inStart > inEnd)return NULL;//取出子樹根節點val = postorder[*postEnd];//指針指向下一個子樹的根節點*postEnd = *postEnd - 1;//中序遍歷查找根節點所在位置for (i = 0; i <= inEnd; i++)if (inorder[i] == val)break;//在劃分后的范圍內繼續查找root的右子樹和左子樹,順序不能搞錯right = findSubTree(inorder, postorder, postEnd, i + 1, inEnd);left = findSubTree(inorder, postorder, postEnd, inStart, i - 1);//組合子樹root = (struct TreeNode *)calloc(1, sizeof(struct TreeNode));root->val = val;root->left = left;root->right = right;return root; }struct TreeNode* buildTree(int* inorder, int inorderSize, int* postorder, int postorderSize){//第一個根節點位置int postEnd = postorderSize - 1;//第一次查找,中序范圍為0~inorderSize - 1。return findSubTree(inorder, postorder, &postEnd, 0, inorderSize - 1); }參考資料:
1.?106. 從中序與后序遍歷序列構造二叉樹_嗶哩嗶哩 (゜-゜)つロ 干杯~-
? ? ?https://www.bilibili.com/video/av45393236
=============================================================================================
Linux應用程序、內核、驅動、后臺開發交流討論群(745510310),感興趣的同學可以加群討論、交流、資料查找等,前進的道路上,你不是一個人奧^_^。
總結
以上是生活随笔為你收集整理的leetcode 106. 从中序与后序遍历序列构造二叉树 c语言递归解法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《剑指offer》c++版本 14.剪绳
- 下一篇: leetcode 450. 删除二叉搜