景兄弟手撕算法之二叉查找树的实现

二叉查找树的定义:

一棵空树,或者是具有下列性质的二叉树:
(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());

    }

}

 

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