剑指offer之重建二叉树
1 問題
重建二叉樹:給定二叉樹的先序遍歷(根左右)和中序(左中右)遍歷結果,建立這棵二叉樹。輸入保證二叉樹無重復結點
以先序{1, 2, 4, 7, 3, 5, 6, 8}和中序{4, 7, 2, 1, 5, 3, 8, 6}為例
?
?
?
?
?
2 分析
先序遍歷的特點,我們知道{1, 2, 4, 7, 3, 5, 6, 8}第一個元素1就是樹的根節點,然后中序遍歷{4, 7, 2, 1, 5, 3, 8, 6}的根節點在中間,因為我們從先序遍歷里面得知1就是根節點,所以在中序遍歷{4, 7, 2, 1, 5, 3, 8, 6}中,在中序遍歷數組1的左邊元素都是根節點左子樹{4, 7, 2,},這里是3個元素,所以在先序數組里面根節點1的后面3個元素也是左子樹{2,4,7},也是根節點的左子樹,在中序遍歷1的右邊邊元素都是{5, 3, 8, 6}都是根節點的右子樹,然后我們在先序數組里面根節點1的后面第3個元素的后面到尾巴,也就是{3,5,6,8}也就是根節點的右子樹。然后我們再把問題分解成構建左子樹{2,4,7}和構建右子樹{3,5,6,8},以此遞歸處理。
我們構建左子樹
再構建右子樹
?
?
?
?
?
?
?
3 代碼實現
import java.io.*;class Tree {public int value;public Tree left;public Tree right;public Tree(int value){this.value = value;this.left = null;this.right = null;}/***前序遍歷 */public void printTree(Tree node){if (null == node)return;System.out.println("value is " + node.value);printTree(node.left);printTree(node.right);}/**得到樹的根節點*/public Tree getTree(int[] preDatas, int[] inDatas){if (null == preDatas || null == inDatas){System.out.println("preDatas is null or inDatas is null");return null;}Tree tree = buildTree(preDatas, 0, preDatas.length - 1, inDatas, 0, inDatas.length - 1);return tree;}/**構建樹的左右子結構*/public Tree buildTree(int[] preDatas, int preStart, int preEnd, int[] inDatas, int inStart, int inEnd){if (null == preDatas || null == inDatas){System.out.println("preDatas is null or inDatas is null");return null;}System.out.println("preStart is:" + preStart + " preEnd is" + preEnd + " inStart is " + inStart + " inEnd is" + inEnd);//這里就是進行如果樹的左子節點和右子節點是否為空進行設置if (preStart > preEnd || inStart > inEnd){return null;}Tree tree = new Tree(preDatas[preStart]);for (int i = inStart; i <= inEnd; ++i){ System.out.println("preDatas[preStart] is " + preDatas[preStart]);if (preDatas[preStart] == inDatas[i]){tree.left = buildTree(preDatas, preStart + 1, preStart + i - inStart, inDatas, inStart, i - 1);tree.right = buildTree(preDatas, preStart + i - inStart + 1, preEnd, inDatas, i + 1, inEnd);break;}}return tree;} }class test {public static void main (String[] args) throws java.lang.Exception{int[] preDatas = {1, 2, 4, 7, 3, 5, 6, 8};int[] inDatas = {4, 7, 2, 1, 5, 3, 8, 6};Tree test = new Tree(0);Tree tree = test.getTree(preDatas, inDatas);if (tree == null){System.out.println("tree is null");return;}//我們進行前序打印樹 test.printTree(tree);} }?
?
?
?
?
?
4 運行結果
preStart is:0 preEnd is7 inStart is 0 inEnd is7 preDatas[preStart] is 1 preDatas[preStart] is 1 preDatas[preStart] is 1 preDatas[preStart] is 1 preStart is:1 preEnd is3 inStart is 0 inEnd is2 preDatas[preStart] is 2 preDatas[preStart] is 2 preDatas[preStart] is 2 preStart is:2 preEnd is3 inStart is 0 inEnd is1 preDatas[preStart] is 4 preStart is:3 preEnd is2 inStart is 0 inEnd is-1 preStart is:3 preEnd is3 inStart is 1 inEnd is1 preDatas[preStart] is 7 preStart is:4 preEnd is3 inStart is 1 inEnd is0 preStart is:4 preEnd is3 inStart is 2 inEnd is1 preStart is:4 preEnd is3 inStart is 3 inEnd is2 preStart is:4 preEnd is7 inStart is 4 inEnd is7 preDatas[preStart] is 3 preDatas[preStart] is 3 preStart is:5 preEnd is5 inStart is 4 inEnd is4 preDatas[preStart] is 5 preStart is:6 preEnd is5 inStart is 4 inEnd is3 preStart is:6 preEnd is5 inStart is 5 inEnd is4 preStart is:6 preEnd is7 inStart is 6 inEnd is7 preDatas[preStart] is 6 preDatas[preStart] is 6 preStart is:7 preEnd is7 inStart is 6 inEnd is6 preDatas[preStart] is 8 preStart is:8 preEnd is7 inStart is 6 inEnd is5 preStart is:8 preEnd is7 inStart is 7 inEnd is6 preStart is:8 preEnd is7 inStart is 8 inEnd is7 value is 1 value is 2 value is 4 value is 7 value is 3 value is 5 value is 6 value is 8?
?
?
?
?
5 總結
中途遇到這個一個錯誤
error: <identifier> expected是我在手寫函數的時候參數前面忘記了定義類型,所以報這個錯誤。
我們這里用了4個指針,分別是先序的起尾指針和中序的起尾指針,然后我們不斷更新4個指針指針的位置,然后當先序的起指針大于尾指針的時候或者中序的起指針大于尾指針的時候我們就構建空指針,就這樣遞歸處理就行。
總結
以上是生活随笔為你收集整理的剑指offer之重建二叉树的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 剑指offer之求二叉树中两个节点的最低
- 下一篇: 剑指offer之partition算法