java實現 二叉樹的常用操作算法:包括二叉樹的建立、遍歷、求高度、線索化等操作

實現二叉樹的常用操作算法:

包括二叉樹的建立、遍歷、求高度、線索化等操作

 

package tree;


public class Tree<T> {
    private treeNode<T> pre ;   //線索化時記錄前一個節點
    public treeNode<T> root;    //根節點
    //聲明節點
    static class treeNode<T> {

        //節點對應存儲的數據
        T value;
        //表示左右孩子的指針是否爲線索,默認是false,非線索
        boolean left = false;
        boolean right = false;
        //左右孩子的指針,此處用的引用
        treeNode<T> leftChild;
        treeNode<T> rightChild;
        treeNode(T value){
            this.value = value;
        }
    }
    public Tree (T array[],int index){
        root = createTree(array,index);
    }

    //首先創樹
    public <T> treeNode createTree(T array[],int index){
        treeNode<T> root = null;
        if(index < array.length) {
            root = new treeNode(array[index]);
            root.leftChild = createTree(array, index * 2 + 1);
            root.rightChild = createTree(array, index * 2 + 2);
        }
        return root;
    }

    public void preTravel(){
        preOrderTravel(root);
        System.out.println("前序遍歷");
    }
    public void midTravel(){
        midOrderTravel(root);
        System.out.println("中序遍歷");
    }
    public void aftTravel(){
        aftOrderTravel(root);
        System.out.println("後序遍歷");
    }
    //前序遍歷
    public <T> void preOrderTravel(treeNode<T> root){
        if (root == null){
            return;
        }else{
            //前中後遍歷其實也就是這下面三行的順序不同
            System.out.print(root.value+" ,");
            preOrderTravel(root.leftChild);
            preOrderTravel(root.rightChild);
        }
    }

    //中序遍歷
    public <T> void midOrderTravel(treeNode<T> root){
        if (root == null){
            return;
        }else{
            //前中後遍歷其實也就是這下面三行的順序不同
            midOrderTravel(root.leftChild);
            System.out.print(root.value+" ,");
            midOrderTravel(root.rightChild);
        }
    }

    //後序遍歷
    public <T> void aftOrderTravel(treeNode<T> root){
        if (root == null){
            return;
        }else{
            //前中後遍歷其實也就是這下面三行的順序不同
            aftOrderTravel(root.leftChild);
            aftOrderTravel(root.rightChild);
            System.out.print(root.value+" ,");
        }
    }

    public void high(){
        System.out.println("樹的高度爲"+depth(root));
    }
    //get樹的深度
    public <T> int depth(treeNode<T> root){
        if(root == null){
            return 0;
        }
        //返還左子樹和右子樹最深的那個,然後加上自己的根節點
        return Math.max(depth(root.leftChild) + 1,depth(root.rightChild) + 1);
    }
    //前序線索化二叉樹並且遍歷
    public void preThread(){
        preThreadOrder(root);
        preThreadList(root);
    }

    void preThreadList(treeNode<T> node) {
        while(node != null) {

            while(!node.left) {
                System.out.print(node.value + ", ");
                node = node.leftChild;
            }

            System.out.print(node.value + ", ");
            node = node.rightChild;
        }
    }

    public void preThreadOrder(treeNode<T> node){
        if(node!=null){
            //左指針爲空時,讓他指向pre的元素
            if(node.leftChild==null){
                node.leftChild = pre;
                node.left=true;
            }
            //前一個節點的後繼節點指向當前節點
            if(pre != null && pre.rightChild == null) {
                pre.rightChild = node;
                pre.right = true;
            }

            pre = node;

            //處理左子樹
            if(!node.left) {
                preThreadOrder(node.leftChild);
            }

            //處理右子樹
            if(!node.right) {
                preThreadOrder(node.rightChild);

            }
        }
    }

    //中序線索化二叉樹並且遍歷
    public void midThread(){
        inThreadOrder(root);
        inThreadList(root);
        inPreThreadList(root);
    }
    //中序線索化二叉樹
    void inThreadOrder(treeNode node) {
        if (node == null) {
            return;
        }

        //處理左子樹
        inThreadOrder(node.leftChild);

        //左指針爲空,將左指針指向前驅節點
        if (node.leftChild == null) {
            node.leftChild = pre;
            node.left = true;
        }

        //前一個節點的後繼節點指向當前節點
        if (pre != null && pre.rightChild == null) {
            pre.rightChild = node;
            pre.right = true;
        }
        pre = node;

        //處理右子樹
        inThreadOrder(node.rightChild);
    }


        void inThreadList(treeNode node) {
        //1、找中序遍歷方式開始的節點
        while(node != null && !node.left) {
            node = node.leftChild;
        }

        while(node != null) {
            System.out.print(node.value + ", ");

            //如果右指針是線索
            if(node.right) {
                node = node.rightChild;

            } else {    //如果右指針不是線索,找到右子樹開始的節點
                node = node.rightChild;
                while(node != null && !node.left) {
                    node = node.leftChild;
                }
            }
        }
    }

    /**
     * 中序遍歷線索二叉樹,按照前驅方式遍歷(思路:找到最右子節點開始倒序遍歷)
     * @param node
     */
    void inPreThreadList(treeNode node) {
        //1、找最後一個節點
        while(node.rightChild != null && !node.right) {
            node = node.rightChild;
        }

        while(node != null) {
            System.out.print(node.value + ", ");

            //如果左指針是線索
            if(node.left) {
                node = node.leftChild;

            } else {    //如果左指針不是線索,找到左子樹開始的節點
                node = node.leftChild;
                while(node.rightChild != null && !node.right) {
                    node = node.rightChild;
                }
            }
        }
    }



    public static void main(String[] args){
        Integer a[] ={1,2,3,4,5,6,7};
        //使用數組創建二叉樹
        Tree<Integer> tree = new Tree<Integer>(a,0);
        //前序遍歷
        tree.preTravel();
        tree.midTravel();
        tree.aftTravel();
        //求高度
        tree.high();
        //線索化
        //tree.preThread();
        tree.midThread();
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章