劍指offer(四)重建二叉樹

tankII發表於2021-09-09

寫在前面:

為了增長一下自己的資料結構能力,也為了面試準備,準備將劍指Offer做一下,並與各位分享,希望各位可以對程式碼以及思路提提建議,歡迎志同道合者,謝謝。

題目:
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。

思路:

首先講一下什麼是二叉樹的中序,前序,後序遍歷,大家也可以看看我這篇,中序,前序,後序,遍歷,大家只需要記住這個是相對於根節點的就好,左子樹和右子樹的順序不變,比如說前序遍歷,也就是先列印根節點,然後列印左子樹然後是右子樹,中序就是先列印左子樹,然後列印根節點,然後列印右子樹,那麼後序想必大家都知道了吧,左子樹,右子樹,根節點,

好了,知道了什麼是前序,中序,後序,,那麼我們看看這三種排序有啥特點呢, 前序已經說了,先列印根節點,也就是前序按順序來,都是根節點,  那麼中序呢,先列印左子樹,然後列印根節點,  那麼我們能不能根據前序的根節點在中序中找到他的左子樹呢,還有右子樹,舉個例子

前序  1,2,4,7,3,5,6,8
中序  4,7,2,1,5,3,8,6

首先1是根節點,那麼中序中1的左邊(4,7,2)全是1的左子樹的節點,右邊(5,3,8,6)全都是右子樹節點,然後我們看左子樹,根節點是2,中序中2的左邊(4,7)都是2的左子樹節點,2的右邊沒有資料,說明他沒有右子樹,依次類推,

注意,每次找到根節點之後,那麼就將中序從根節點分為兩部分,左邊是左子樹,右邊是右子樹,然後分別進行遞迴,

好了,現在正式進入程式碼環節

package com.itzmn.offer;import javax.swing.tree.TreeNode;/**
 * @Auther: 張夢楠
 * @Date: 2018/7/28 08:12
 * 簡書:
 * 碼雲:
 * @Description:  重建二叉樹
 *
 *   輸入前序與中序,還原出二叉樹,
 *
 *   前序的每一個都是根節點,根據根節點在中序中尋找,左邊的就是左子樹的節點,右邊的就右子樹的節點
 *
 */public class Offer4 {    public static void main(String[] args) {        int[] pre = {1,2,4,7,3,5,6,8};        int[] in =  {4,7,2,1,5,3,8,6};
        TreeNode treeNode = new Offer4().reConstructBinaryTree(pre, in);        new Offer4().printpreTree(treeNode);
    }    public TreeNode reConstructBinaryTree(int [] pre, int [] in) {        if (pre.length == 0 || in.length == 0 || pre.length != in.length){
            System.out.println("您輸入的資料不合法");            return null;
        }        return createBinaryTree(pre,0,pre.length-1,in , 0 , in.length-1);
    }    /**
     *
     * @param pre  前序遍歷
     * @param preB  前序遍歷開始的座標
     * @param preE  前序遍歷最終座標
     * @param in  中序遍歷
     * @param inB  中序遍歷開始位置
     * @param inE  中序遍歷結束位置
     * @return   返回二叉樹根節點
     */
    private TreeNode createBinaryTree(int[] pre, int preB, int preE, int[] in, int inB, int inE) {        if (preB >preE){            return null;
        }        /**
         *  從前序遍歷中尋找根節點
         *  根據根節點在中序遍歷中找到左右子樹
         */
        //這是根節點的值,
        int value = pre[preB];        int index = inB;        // 在中序遍歷中找到這個根節點
        while (index <= inE && in[index] != value){
            index++;
        }        // 判斷中序中是否有這個根節點

        if (index > inE){           throw new RuntimeException("輸入的資料有問題");
        }


        TreeNode treeNode = new TreeNode(value);        /**
         *  構建左子樹
         */
        treeNode.left = createBinaryTree(pre,preB+1,preB+index-inB,in,inB,index-1);

        treeNode.right = createBinaryTree(pre,preB+index-inB+1,preE,in,index+1,inE);        return treeNode;
    }    /**
     *  輸出數的前序遍歷
     * @param treeNode
     */
    public void printpreTree(TreeNode treeNode){

        System.out.println(treeNode.val);        if (treeNode.left != null){
            printpreTree(treeNode.left);
        }        if (treeNode.right != null){
            printpreTree(treeNode.right);
        }

    }    public class TreeNode {      int val;
      TreeNode left;
      TreeNode right;
      TreeNode(int x) { val = x; }

  }





}



作者:z七夜
連結:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1795/viewspace-2818078/,如需轉載,請註明出處,否則將追究法律責任。

相關文章