Java数据结构与算法:二叉排序树BST、二叉排序树添加删除、代码实现


二叉排序树 BST

二叉排序树:BTS(Binary Sort Tree),对于二叉排序树的任何一个非叶子节点,要求左子节点的值比当前节点的值小,右子节点的值比当前节点的值大。如果有相同的值,可以将该节点放在左子节点或右子节点。

二叉排序树的中序遍历,结果就是从小到大的排列。

二叉排序树的特点:

  • 左子树所有的值一定比根节点小,右子树所有的值一定比根节点大

1、二叉排序树 添加


1)思路分析

  • 添加的node的值小于当前节点的值,那么就判断当前节点的左节点是否为空;为空就直接挂在当前节点的左边,不为空就继续往左节点往下找
  • 添加的node的值大于等于当前节点的值,那么就判断当前节点的右节点是否为空;为空就直接挂在当前节点的右边,不为空就继续往右节点往下找

2)代码实现

public class BinarySortTreeDemo {
    public static void main(String[] args) {
        int arr[] = {7,3,10,12,5,1,9};
        BinarySortTree binarySortTree = new BinarySortTree();
        for (int i = 0; i < arr.length; i++) {
            binarySortTree.add(new BstNode(arr[i]));
        }
        binarySortTree.infixOrder();
    }
}

// 二叉排序树
class BinarySortTree{
    private BstNode root;

    public BinarySortTree() {
    }

    public BinarySortTree(BstNode root) {
        this.root = root;
    }

    public void infixOrder(){
        if (root==null){
            return;
        }else {
            root.infixOrder();
        }
    }

    public void add(BstNode node){
        if (root==null){
            root = node;
        }else {
            root.add(node);
        }
    }
}

// 节点
class BstNode{
    int value;
    BstNode left;
    BstNode right;

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

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

    public void infixOrder(){
        if (this.left!=null){
            this.left.infixOrder();
        }
        System.out.println(this.toString());
        if (this.right!=null){
            this.right.infixOrder();
        }
    }

    // 二叉排序树添加
    public void add(BstNode node){
        if (node == null){
            return;
        }
        // 添加的node的值小于当前节点的值,那么就判断当前节点的左节点是否为空
        // 为空就直接挂在当前节点的左边,不为空就继续往左节点往下找
        if (node.value < this.value){
            if (this.left!=null){
                this.left.add(node);
            }else {
                this.left = node;
            }
        }else {// 添加的node的值大于等于当前节点的值,那么就判断当前节点的右节点是否为空
               // 为空就直接挂在当前节点的右边,不为空就继续往右节点往下找
            if (this.right!=null){
                this.right.add(node);
            }else {
                this.right = node;
            }
        }
    }
}

结果:

BstNode{value=1}
BstNode{value=3}
BstNode{value=5}
BstNode{value=7}
BstNode{value=9}
BstNode{value=10}
BstNode{value=12}

2、二叉排序树 删除


1)思路分析

在这里插入图片描述

删除有三种情况:

  1. 目标节点没有任何子节点

    定位到目标节点的父节点,如果目标节点是其父节点的右子节点,那么将其父节点的右子节点置为空即可;如果目标节点是父节点的左子节点,那么将其父节点的左子节点置为空即可。

  2. 目标节点有一个子节点

    定位目标节点的父节点,如果目标节点是其父节点的左子节点,那么将其父节点的左子节点指向目标节点的子节点;如果目标节点是其父节点的右子节点,那么将其父节点的右子节点指向目标节点的子节点;如果目标节点的父节点为空,说明删除的目标节点是根节点,那么直接将根节点指向目标节点的子节点即可;。

  3. 目标节点有两个子节点

    定位目标节点,找到目标节点的右子节点中最小的节点,将该最小的节点临时保存下来,并删除,将目标节点重新赋值为该最小的节点。


2)代码实现

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 i = 0; i < arr.length; i++) {
            binarySortTree.add(new BstNode(arr[i]));
        }
        System.out.println("原二叉排序树中序遍历结果:");
        binarySortTree.infixOrder();
        System.out.println("删除有一个子节点的目标节点:1");
        binarySortTree.del(1);
        System.out.println("删除有两个子节点的目标节点:10");
        binarySortTree.del(10);
        System.out.println("删除没有子节点的目标节点:2");
        binarySortTree.del(2);
        System.out.println("最终中序遍历结果:");
        binarySortTree.infixOrder();
    }
}

// 二叉排序树
class BinarySortTree{
    private BstNode root;

    public BinarySortTree() {
    }

    public BinarySortTree(BstNode root) {
        this.root = root;
    }

    public void infixOrder(){
        if (root==null){
            return;
        }else {
            root.infixOrder();
        }
    }

    public void add(BstNode node){
        if (root==null){
            root = node;
        }else {
            root.add(node);
        }
    }

    // 获得需要删除的目标节点
    public BstNode getDelTargetNode(int value){
        if (root==null){
            return null;
        }else {
            return root.getDelTargetNode(value);
        }
    }

    // 获得需要删除的目标节点的父节点
    public BstNode getDelTargetParentNode(int value){
        if (root==null){
            return null;
        }else {
            return root.getDelTargetParentNode(value);
        }
    }

    // 找最小值的节点
    public BstNode getRightMinNode(BstNode node){
        if (node==null){
            return null;
        }
        while (node.left!=null){
            node = node.left;
        }
        del(node.value); // 删除这个节点
        return node;
    }

    // 删除节点操作
    public void del(int value){
        BstNode targetNode = getDelTargetNode(value);
        if (targetNode == null){
            return;
        }
        // 如果targetNode不为空,并且root节点没有左右节点肯定就是删除root节点,直接置空即可
        if (root.left == null && root.right == null){
            root = null;
            return;
        }
        BstNode parentNode = getDelTargetParentNode(value);
        if (targetNode.left==null && targetNode.right==null){
            // 左右节点都为空,说明是叶子节点
            if (parentNode.left!=null && parentNode.left.value == value){
                parentNode.left = null;
            }else {
                parentNode.right = null;
            }
        }else if (targetNode.left!=null && targetNode.right!=null){
            // 左右节点都不为空,说明删除的是有左右子树的节点
            BstNode rightMinNode = getRightMinNode(targetNode.right);
            targetNode.value = rightMinNode.value; // 把值赋给目标节点
        }else {
            // 说明目标节点有一个子节点
            if (targetNode.left!=null){
                if (parentNode!=null){
                    if (parentNode.left!=null && parentNode.left.value == value){
                        parentNode.left = targetNode.left;
                    }else {
                        parentNode.right = targetNode.left;
                    }
                }else {
                    root = targetNode.left;
                }
            }else {
                if (parentNode!=null){
                    if (parentNode.left!=null && parentNode.left.value == value){
                        parentNode.left = targetNode.right;
                    }else {
                        parentNode.right = targetNode.right;
                    }
                }else {
                    root = targetNode.right;
                }
            }
        }
    }
}

// 节点
class BstNode{
    int value;
    BstNode left;
    BstNode right;

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

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

    public void infixOrder(){
        if (this.left!=null){
            this.left.infixOrder();
        }
        System.out.println(this.toString());
        if (this.right!=null){
            this.right.infixOrder();
        }
    }

    // 二叉排序树添加
    public void add(BstNode node){
        if (node == null){
            return;
        }
        // 添加的node的值小于当前节点的值,那么就判断当前节点的左节点是否为空
        // 为空就直接挂在当前节点的左边,不为空就继续往左节点往下找
        if (node.value < this.value){
            if (this.left!=null){
                this.left.add(node);
            }else {
                this.left = node;
            }
        }else {// 添加的node的值大于等于当前节点的值,那么就判断当前节点的右节点是否为空
               // 为空就直接挂在当前节点的右边,不为空就继续往右节点往下找
            if (this.right!=null){
                this.right.add(node);
            }else {
                this.right = node;
            }
        }
    }

    // 找到需要删除的目标节点
    public BstNode getDelTargetNode(int value){
        if (this.value == value){
            return this;
        }
        if (value < this.value){
            if (this.left!=null){
                return this.left.getDelTargetNode(value);
            }else {
                return null;
            }
        }else {
            if (this.right!=null){
                return this.right.getDelTargetNode(value);
            }else {
                return null;
            }
        }
    }

    // 找到需要删除的目标节点的父节点
    public BstNode getDelTargetParentNode(int value){
        // 如果当前节点的左右节点中有一个的值为value,就返回该节点,就是value值节点的父节点
        if (this.left!=null && this.left.value == value || this.right!=null && this.right.value == value){
            return this;
        }
        // 不满足以上要求,说明需要继续找,
        // 如果value小于当前节点的value,就在当前节点的左节点找,
        // 如果value大于等于当前节点的value,就在当前节点的右节点找,
        if (value < this.value){
            if (this.left!=null){
                return this.left.getDelTargetParentNode(value);
            }else {
                return null;
            }
        }else {
            if (this.right!=null){
                return this.right.getDelTargetParentNode(value);
            }else {
                return null;
            }
        }
    }
}

结果:

原二叉排序树中序遍历结果:
BstNode{value=1}
BstNode{value=2}
BstNode{value=3}
BstNode{value=5}
BstNode{value=7}
BstNode{value=9}
BstNode{value=10}
BstNode{value=12}
删除有一个子节点的目标节点:1
删除有两个子节点的目标节点:10
删除没有子节点的目标节点:2
最终中序遍历结果:
BstNode{value=3}
BstNode{value=5}
BstNode{value=7}
BstNode{value=9}
BstNode{value=12}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值