輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。
思路:根據二叉樹的定義。
前序遍歷:1.遍歷root根節點
2.前序遍歷左子樹
3.前序遍歷右子樹
根據前序遍歷的結果可知第一個訪問的必定是root結點。
中序遍歷:1.中序遍歷左子樹
2.遍歷root根節點
3.中序遍歷右子樹
根據中序遍歷的結果,再結合前序遍歷的root結點去劃分root結點的左右子樹。
後序遍歷:1.後序遍歷左子樹
2.後序遍歷右子樹
3.遍歷root根節點
根據後序遍歷的結果可知最後訪問的必定是root結點。
示例:
假如有如下的二叉樹:
根據上面的定義,得出如下的遍歷結果
前序遍歷:ABDHIEJCFKG
中序遍歷:HDIBEJAFKCG
後序遍歷:HIDJEBKFGCA
由此可知根據前序遍歷和中序遍歷的結果則可重建二叉樹
function TreeNode(x) { this.val = x;//當前節點的數據域 this.left = null;//指針左移 this.right = null;//指針右移 } function reConstructBinaryTree(pre, vin) { var root=0,i,j; var left_pre=[],left_vin=[],right_pre=[],right_vin=[]; if(vin.length===0){ return null; } var head = new TreeNode(pre[0]);//pre[0]即爲根節點 for(i=0;i<vin.length;i++){ if(vin[i]===pre[0]){ root=i;//從中序遍歷的數組中找到根節點的位置 break; } } for(j=0;j<root;j++){ left_pre.push(pre[j+1]);//左子樹的前序遍歷放置在left_pre數組中 left_vin.push(vin[j]);//左子樹的中序遍歷放置在left_vin數組中 } for(j=root+1;j<vin.length;j++){ right_pre.push(pre[j]);//右子樹的前序遍歷放置在right_pre數組中 right_vin.push(vin[j]);//右子樹的中序遍歷放置在right_vin數組中 } head.left= reConstructBinaryTree(left_pre,left_vin);//遞歸遍歷左子樹 head.right= reConstructBinaryTree(right_pre,right_vin);//遞歸遍歷右子樹 return head; }