个人学习之二叉排序树

声明:感谢尚硅谷的公开资料

二叉排序树

image-20210805155656615

image-20210805155719279

image-20210805155802372

image-20210805155854136

package dataStructure.binarySortTree;

/**
 * 二叉排序
 */
public class BinarySortTreeDemo {
    public static void main(String[] args) {
        int[] arr = {7, 3, 10, 12, 5, 1, 9, 2};
        BinarySortTree binarySortTree = new BinarySortTree();
        // 循环添加
        for (int v : arr) {
            binarySortTree.add(new Node(v));
        }
        // 删除前遍历
        binarySortTree.infixOrder();// 1、3、5、7、9、10、12
        // System.out.println("删除叶子结点");
        // 删除叶子结点
        // binarySortTree.delNode(12);
        /*System.out.println("删除只有一颗子树的结点");
        binarySortTree.delNode(1);*/
        System.out.println("删除有两颗子树的结点");
        binarySortTree.delNode(10);
        // 删除后遍历
        binarySortTree.infixOrder();
    }
}

// 创建二叉排序树
class BinarySortTree {
    private Node root;

    // 查找要删除的结点
    public Node search(int value) {
        if (null == root) {
            return null;
        }
        return root.search(value);
    }

    // 查找要删除的结点的父节点
    public Node searchParent(int value) {
        if (null == root) {
            return null;
        }
        return root.searchParent(value);
    }

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

    public int delLeftTreeMin(Node node) {
        Node target = node;
        while (null != target.right) {
            // 循环查找左子结点,就会找到最小值
            target = target.right;
        }
        // 这是target指向了最小结点
        // 删除最小结点
        delNode(target.value);
        return target.value;
    }

    // 删除节点
    public void delNode(int value) {
        if (null == root) {
            return;
        }
        // 先查找删除的结点
        Node targerNode = search(value);
        if (null == targerNode) {
            // 没找到删除的结点
            return;
        }
        // targerNode没有父结点时,这颗二叉排序树只有一个结点
        if (null == root.left && null == root.right) {
            root = null;
            return;
        }
        // 查找targetNode的父结点
        Node targetParent = searchParent(value);

        if (null == targerNode.left && null == targerNode.right) {
            // 如果删除的是叶子结点
            // 判断targetNode是targetParent的左子结点还是右子结点
            if (null != targetParent.left && targetParent.left.value == value) {
                targetParent.left = null;
            } else if (null != targetParent.right && targetParent.right.value == value) {
                targetParent.right = null;
            }
        } else if (null != targerNode.left && null != targerNode.right) {
            // 删除有两颗子树
            // int minValue = delRightTreeMin(targerNode.right);
            // targerNode.value = minValue;
            int maxValue = delLeftTreeMin(targerNode.left);
            targerNode.value = maxValue;
        } else {
            // 删除只有一颗子树
            if (null != targerNode.left) {
                if(null != targetParent){
                    // 如果待删除结点有左子结点
                    if (targetParent.left.value == value) {
                        // 如果待删除的点是其父结点的左子结点
                        targetParent.left = targerNode.left;
                    } else {
                        // 如果待删除的点是其父结点的右子结点
                        targetParent.right = targerNode.left;
                    }
                }else{
                    root = targerNode.left;
                }

            } else {
                if(null != targetParent){
                    // 如果待删除结点有右子结点
                    if (targetParent.left.value == value) {
                        // 如果待删除的点是其父结点的左子结点
                        targetParent.left = targerNode.right;
                    } else {
                        // 如果待删除的点是其父结点的右子结点
                        targetParent.right = targerNode.right;
                    }
                }else{
                    root = targerNode.right;
                }
            }
        }
    }

    // 添加结点的方法
    public void add(Node node) {
        if (null == root) {
            // 空树状态
            root = node;
        } else {
            root.add(node);
        }
    }

    // 中序遍历的方法
    public void infixOrder() {
        if (null == root) {
            System.out.println("二叉排序树为空,无法遍历");
            return;
        }
        root.infixOrder();
    }
}

// 创建结点
class Node {
    int value;
    Node left;
    Node right;

    public Node(int value) {
        this.value = value;
    }
    // 查找要删除的结点

    /**
     * @param value 要删除的结点的值
     * @return 返回该结点,否则为空
     */
    public Node search(int value) {
        if (value == this.value) {
            // 找到该结点
            return this;
        } else if (value < this.value) {
            if (null != this.left) {
                return this.left.search(value);
            } else {
                // 左子树为空
                return null;
            }
        } else {
            if (null != this.right) {
                return this.right.search(value);
            } else {
                // 右子树为空
                return null;
            }
        }
    }
    // 查找待删除结点的父结点

    /**
     * @param value 待删除结点
     * @return 返回待删除结点的父结点 否则为空
     */
    public Node searchParent(int value) {
        if ((null != this.left && this.left.value == value)
                || (null != this.right && this.right.value == value)) {
            return this;
        } else {
            // 查找的值小于当前结点的值,并且当前结点的左子结点不为空
            if (value < this.value && null != this.left) {
                // 向左子树递归查找
                return this.left.searchParent(value);
            } else if (value >= this.value && null != this.right) {
                // 向右子树递归查找
                return this.right.searchParent(value);
            } else {
                // 没有找到父节点
                return null;
            }
        }
    }

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

    // 添加结点方法
    // 递归形式添加,满足二叉排序要求
    public void add(Node node) {
        if (null == node) {
            return;
        }
        // 判断传入的结点的值和当前子树的根结点的值关系
        if (node.value < this.value) {
            // 当前左子结点为空
            if (null == this.left) {
                this.left = node;
            } else {
                // 递归向左子树添加
                this.left.add(node);
            }
        } else {
            // 当前右子结点为空
            if (null == this.right) {
                this.right = node;
            } else {
                // 递归向右子树添加
                this.right.add(node);
            }
        }
    }

    // 中序遍历
    public void infixOrder() {
        if (null != this.left) {
            this.left.infixOrder();
        }
        System.out.println(this);
        if (null != this.right) {
            this.right.infixOrder();
        }
    }
}
        }
    }

    // 中序遍历
    public void infixOrder() {
        if (null != this.left) {
            this.left.infixOrder();
        }
        System.out.println(this);
        if (null != this.right) {
            this.right.infixOrder();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值