二叉排序树代码实现(java)

二叉排序树说明:
若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
左、右子树也分别为二叉排序树;
如果有相等的值,可以放在右边或左边(经量避免相同的值);

示意图:[ 5, 8, 9, 4, 1, 3, 2 ,6, 7];

删除思路:我建议可以不看思路,我写的有点乱,最快的方法就是代码赋值粘贴,debug走一走(代码上都有注释这个很容易理解,因为是在代码中把注释拆分开了),如果不懂二叉树的同学建议先学二叉树,不然会很懵

1)删除一个叶子节点;
1.1)首先找到需要删除的节点 node;
1.2)找到 node 的父节点 parent;
1.3)然后判断 node 是 parent 的左节点还是右节点,如果是左节点直接置空 parent.left = null;如果是右节点,则置空右节点;

2)删除一个带有一个节点的非叶子节点;比如(3)
2.1)首先找到需要删除的节点 node;
2.2)找到 node 的父节点 parent;
2.3)判断 node 是有左节点还是右节点;
2.4)判断 parent 的左节点如果不等于空,并且 parent 的左节点等于 node 说明需要删除的节点是parent的左节点;
2.5)如果 node 有左节点则让 parent.left = node.left;如果 node 有右节点则让 parent.left = right;
2.6)如果 node 有右节点则反之;

3)删除一个二叉树;
3.1)首先找到需要删除的节点 node;
3.2)找到 node 的父节点 parent;
3.3)找到以 node 的右节点为根节点最小的节点,用示意图比较,删除8,就找到以9 为根节点最小的节点,9 没有左节点,所以 9 就是最小的节点;
3.4)将 9 赋值给node,完成删除二叉树;

代码实现二叉排序树:

public class SortTreeDemo {

    public static void main(String[] args){
        int arr[] = {8,9,1,6,7,5,4,3,2};

        Tree tree = new Tree();
        for (int i = 0; i <arr.length ; i++) {
            tree.insert(new Node(arr[i]));
        }

        tree.inOrder();
        System.out.println();

        tree.findDeleteNode(6);
        tree.findDeleteNode(5);
        tree.findDeleteNode(8);
        tree.inOrder();
    }

}


class Tree{

    private Node root;  // 根节点


    /**
     * @param node  传入的节点 (当作二叉排序树的根节点)
     * @return  返回以node为根节点的二叉排序树最小节点
     */
    public int delRightTreeMin(Node node){
        Node target = node;
        // 循环找左子节点,找到最小左子节点为止;
        while (target.left != null) {
            target = target.left;
        }
        // 这是target指向最小节点
        // 删除最小节点
        findDeleteNode(target.value);
        // 然后返回最小节点值
        return target.value;
    }


    // 删除节点
    public void findDeleteNode(int value){
        if (root == null){
            System.out.println("com.zhang.tree.Tree.findDeleteNode:跟节点为空");
        }else{
            // 需要删除的节点
            Node node = root.findNode(value);
            if (node == null){
                System.out.println("没有需要删除的节点");
            }
            // 因为删除节点,可能存在没有父节点的情况
            // 比如开始就要删除root
            if (root.left == null && root.right == null){
                root = null;
                return;
            }

            // 需要删除节点的父节点
            Node parent = root.findParent(value);

            // node:需要删除的节点
            // 1、node左右节点都为空,直接删除即可
            if (node.left == null && node.right == null){
                // 如果需要删除节点的父节点,左节点不为空,并且等于需要删除的节点,直接删除
                if (parent.left != null && parent.left.value == value){
                    parent.left = null;
                }else if (parent.right != null){
                    parent.right = null;
                }
            }else if (node.left != null && node.right != null){ // 2、node左右节点都不为空
                // 找到node右子树的最小节点,然后删除掉,
                // 在返回最小节点
                int min = delRightTreeMin(node.right);
                // min现在就是node右子树的最小节点
                // 赋值给node,完成删除node
                node.value = min;
            }else { // 3、node左右节点有一个节点为空

                if (node.left != null){ // 说明node有左子节点
                    // 判断node是node父节点的左子节点还是右子节点
                    if (parent.left != null && parent.left.value == value){
                        // 是左节点
                        parent.left = node.left;
                    }else{
                        // 是右节点
                        parent.right = node.left;
                    }
                }else { // 说明node有右子节点
                    if (parent.left != null && parent.left.value == value){
                        // 是左节点
                        parent.right = node.right;
                    }else{
                        // 是右节点
                        parent.right = node.right;
                    }
                }

            }
        }

    }


    // 插入节点
    public void insert(Node node){
        if (root == null){
            this.root = node;
            return;
        }
        root.insert(node);
    }



    // 中序遍历
    public void inOrder(){
        if (root != null){
            root.inOrder();
        }else {
            System.out.println("com.zhang.tree.Tree.inOrder:二叉排序树为空");
        }
    }
}



class Node{
    int value;
    Node left;
    Node right;

    public Node(int value){
        this.value = value;
    }

    // 遍历
    public void inOrder(){
        if (this.left != null){
            this.left.inOrder();
        }

        System.out.println(this);

        if (this.right != null){
            this.right.inOrder();
        }
    }


    /**
     * 查找需要删除的节点
     * @param value 希望删除节点的value
     * @return  返回需要删除的节点
     */
    public Node findNode(int value){
        // 首先判断当前节点是否是需要删除的节点
        if (this.value == value){
            return this;
        }else if (this.value > value){  // value小于当前节点
            // 当前节点右子节点等于空,直接返回
            if (this.left == null){
                return null;
            }
            // 左递归查找
            return this.left.findNode(value);
        }else { // value大于当前节点
            // 当前节点右子节点等于空,直接返回
            if (this.right == null){
                return null;
            }
            // 右递归查找
            return this.right.findNode(value);
        }
    }


    /**
     * 查找需要删除的父节点
     * @param value 希望删除的节点的value
     * @return  返回需要删除的父节点
     */
    public Node findParent(int value){
        // 如果当前节点的左右子节点,有一个是需要删除的节点,则返回当前节点
        if ((this.left != null && this.left.value == value) ||
                (this.right != null && this.right.value == value)){
            return this;
        }else {
            // 当前节点的左子节点大于需要删除节点,则左递归查找
            if (this.left != null && this.value > value){
                return this.left.findParent(value);
            }else if (this.right != null && this.value <= value){
                return this.right.findParent(value);
            }
        }

        // 没有找到父节点
        return null;

    }


    // 插入
    public void insert(Node node){
        if (node == null){
            System.out.println("com.zhang.tree.Tree.insert:插入数据不可能为空");
            return;
        }

        // 规则:value值小的放左边,大的或等于放右边
        if (node.value < this.value){   // 小于
            if (this.left != null){ // 如果不等于空,就左递归
                this.left.insert(node);
            }else{  // 为空,直接讲node赋值到当前节点的左子节点
                this.left = node;
            }
        }else { // 大于等于
            if (this.right != null){
                this.right.insert(node);
            }else {
                this.right = node;
            }
        }

    }


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

}

后续会发布二叉树教学,如果觉得可以请点一波赞;点赞就是对我最好的鼓励谢谢大家;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值