景兄弟手撕算法之二叉查找樹的實現

二叉查找樹的定義:

一棵空樹,或者是具有下列性質的二叉樹:
(1)若左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;
(2)若右子樹不空,則右子樹上所有結點的值均大於它的根結點的值;
(3)左、右子樹也分別爲二叉查找樹;
(4)沒有鍵值相等的結點。

Java代碼實現:

package tree;
/**
 * 定義二叉查找樹的數據結構 【鏈表結構】
 */
public class BSTree {

    //父節點
    Node parent;

    public Node find(int value){
        while (parent!=null){
            if(parent.value>value){
                parent = parent.left;
            }else if(parent.value<value){
                parent = parent.right;
            }else {
                return parent;
            }
        }

        return null;
    }

    //向二叉查找樹中插入
    public boolean put(int value){
        if(parent == null){
            //如果要插入的二叉查找樹是一顆空樹
           parent =  createNode(value);
           return true;
        }
        Node pt = parent;
        while (pt!=null){
            if(pt.value > value){
                //當前我們要插入的數據應該存儲再左子樹
                if(pt.left == null){
                    pt.left = createNode(value);
                    return true;
                }
                pt = pt.left;
            }else if(value>pt.value){
                //當前我們要插入的數據應該存儲再右子樹
                if (pt.right==null){
                    pt.right = createNode(value);
                    return true;
                }
                pt = pt.right;
            }
        }
        return false;
    }

    /**
     * 刪除二叉查找樹的某個節點
     * @param value
     */
    public void delete(int value){
        //記錄要刪除的節點
        Node p = parent;
        //記錄要刪除的節點的父節點
        Node p_parent = null;
        //先找到要刪除的元素及其父元素
        while (p!=null){
            if(p.value>value){
                p_parent = p;
                p = p.left;
            }else if (p.value<value){
                p_parent = p;
                p = p.right;
            }else {
                break;
            }
        }
        if (p==null){
            return;
        }

        //要刪除的節點有兩個子節點
        if (p.left!=null &&p.right!=null){
            Node rTree = p.right;
            Node rTree_p = p;//rTree 父節點
            while (rTree.left!=null){
                rTree_p = rTree;
                rTree = rTree.left;
            }

            //用右子樹中的最小節點替換要刪除的節點的位置
            p.value = rTree.value;
            p = rTree;
            p_parent = rTree_p;
        }

        //當我們要刪除的節點是葉子節點,或者只有一個葉子的節點
        Node child = null;
        if (p.right!=null){
            child = p.right;
        }else if(p.left!=null){
            child = p.left;
        }else {
            child = null;
        }

        //執行刪除操作
        if (p_parent==null){
            parent = child;
        }else if (p_parent.left==p){
            p_parent.left = child;
        }else {
            p_parent.right = child;
        }
    }

    /**
     * 構造一個沒有左右子樹的節點
     * @param value
     * @return
     */
    private Node createNode(int value){
        return new Node(null,value,null);
    }

    /**
     * 構造一個有左右子樹的節點
     * @return
     */
    private Node createNode(Node left,int value,Node right){
        return new Node(left, value, right);
    }

    /**
     * 構建節點
     */
    private static class Node{
        private int value;

        private Node left;

        private Node right;

        protected Node(Node left,int value,Node right){
            this.left = left;
            this.value = value;
            this.right = right;
        }

        public int getValue() {
            return value;
        }

        public void setValue(int value) {
            this.value = value;
        }

        public Node getLeft() {
            return left;
        }

        public void setLeft(Node left) {
            this.left = left;
        }

        public Node getRight() {
            return right;
        }

        public void setRight(Node right) {
            this.right = right;
        }

        @Override
        public String toString() {
            return "Node{" +
                    "value=" + value +
                    ", left=" + left +
                    ", right=" + right +
                    '}';
        }
    }

    @Override
    public String toString() {
        return "BSTree{" +
                "parent=" + parent.toString() +
                '}';
    }

    public static void main(String[] args) {
        BSTree bsTree = new BSTree();
        bsTree.put(16);
        bsTree.put(14);
        bsTree.put(35);
        bsTree.put(12);
        bsTree.put(15);
        bsTree.put(25);
        bsTree.put(40);
        bsTree.put(10);
        bsTree.put(20);
        bsTree.put(27);
        bsTree.put(38);
        bsTree.put(41);
        bsTree.put(26);
        bsTree.put(30);
        bsTree.put(39);

        bsTree.delete(10);
        bsTree.delete(38);
        bsTree.delete(25);
        System.out.println(bsTree.toString());

    }

}

 

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