BST二叉排序树代码实现

二叉排序树

基本介绍

二叉排序树:BST: (Binary Sort(Search) Tree), 对于二叉排序树的任何一个非叶子节点,要求左子节点的值比当前节点的值小,右子节点的值比当前节点的值大

  • 特别说明:如果有相同的值,可以将该节点放在左子节点或右子节点

类似于这样一组数据 (7, 3, 9, 1, 4, 8, 15, 2) ,依次加入后对应的二叉排序树应为:
在这里插入图片描述

添加节点

添加的思路较简单,从根节点开始遍历添加,如果值比当前节点小,则向左子节点递归添加,如果比当前节点大,则向右子节点递归添加;

删除节点

  1. 先找到需要删除的节点;

  2. 再找到需要删除的节点的父节点;

  3. 判断需要删除的节点是以下那种类型:

a. 删除叶子节点,判断待删除节点是其父节点的左孩子还是右孩子,然后让其令为空;

b. 删除只有一颗子树的节点(如删除值为1的节点),判断待删除节点是其父节点的左孩子还是右孩子,判断待删除节点的子树是其左孩子还是右孩子,让父节点指向待删除节点的子树指向待删除节点的子树;

c. 删除有两颗子树的节点(如删除值为3的节点),判断待删除节点是其父节点的左孩子还是右孩子,顺着待删除节点的右子树,找到一个值最小的节点(该值的大小最接近待删除节点的值),让父节点指向待删除节点的子树指向上一步找到的最小的节点;

d. 删除根节点(如删除值为7的节点),删除根结点的方法和删除有两个子树的方法相似,找到一个接近根节点值的节点,删除该节点,将该节点的值赋值给根节点即可;

代码实现

/**
 *@ClassName BinarySortTreeTest
 *@Description 二叉排序树 代码实现
 **/
public class BinarySortTreeTest {

    public static void main(String[] args) {
        BinarySortTree sortTree = new BinarySortTree();
        sortTree.add(new BSTNode(7));
        sortTree.add(new BSTNode(3));
        sortTree.add(new BSTNode(9));
        sortTree.add(new BSTNode(4));
        sortTree.add(new BSTNode(15));
        sortTree.add(new BSTNode(8));
        sortTree.add(new BSTNode(1));
        sortTree.add(new BSTNode(2));
        System.out.println("前序排列:");
        sortTree.prePrint();
        System.out.println("删除后:");
        sortTree.delNode(2);
        sortTree.prePrint();
    }


}
/** 二叉排序树代码实现*/
class BinarySortTree {
    BSTNode root;

    /**
     * @Description 每个节点的左子节点小于该节点,右子节点大于该节点
     **/
    public void add(BSTNode newNode) {
        if (root == null) {
            root = newNode;
            return;
        }
        root.add(newNode);
    }

    /**
     * @Author tangjian
     * @Description 删除节点方法
     * 思路:
     * 1. 先找到需要删除的节点
     * 2. 再找到需要删除的节点的父节点
     * 3. 判断需要删除的节点是以下那种类型
     *  a. 叶子节点
     *  b. 有一个子节点的节点
     *  c. 有两个子节点的节点 两种方法 1.找到右子树中最左节点  2. 找到左子中的最右节点 找到后与targetNode设置为该节点
     **/
    public void delNode(int value) {
        BSTNode targetNode = select(value);
        if (targetNode == null) {
            System.out.println("要删除节点不存在");
        }
        BSTNode parentNode = selectParent(targetNode.value);
        if (targetNode.left == null && targetNode.right == null) { //删除叶子节点
            if (parentNode.left == targetNode) {
                parentNode.left = null;
                return;
            }
            if (parentNode.right == targetNode) {
                parentNode.right = null;
                return;
            }
            return;
        } else if (targetNode.left != null && targetNode.right != null) { //删除具有两个子节点的节点
            //获取右子树最小子树
            int rightMinValue = getRightMinNode(targetNode.right);
            delNode(rightMinValue);
            targetNode.value = rightMinValue;
            return;
        } else { //删除具有一个子节点的节点
            if (targetNode.left != null && targetNode.right == null) {
                if (parentNode == null) { //如果parent为null 说明此时只有两个节点删除的是root节点 那个此时直接将left变为root
                    root = targetNode.left;
                    return;
                }
                if (parentNode.left == targetNode) {
                    parentNode.left = targetNode.left;
                    return;
                }
                if (parentNode.right == targetNode) {
                    parentNode.right = targetNode.left;
                    return;
                }
            }
            if (targetNode.right != null && targetNode.left == null) {
                if (parentNode == null) { //如果parent为null 说明此时只有两个节点删除的是root节点 那个此时直接将left变为root
                    root = targetNode.right;
                    return;
                }
                if (parentNode.left == targetNode) {
                    parentNode.left = targetNode.right;
                    return;
                }
                if (parentNode.right == targetNode) {
                    parentNode.right = targetNode.right;
                    return;
                }
            }
        }
    }

    public BSTNode select(int value) {
        if (root == null) {
            System.out.println("当前BST为null");
        }
        return root.select(value);
    }

    public BSTNode selectParent(int value) {
        if (root == null) {
            System.out.println("当期那BST为null");
            return null;
        }
        if (root.value == value) {
            return null;
        }
        return root.selectParent(value);
    }

    public int getRightMinNode(BSTNode targetNode) {
        BSTNode temp = targetNode;
        while (temp.left != null) {
            temp = temp.left;
        }
        return temp.value;
    }

    public void prePrint() {
        if (root == null) {
            System.out.println("当前BST为null");
        }
        root.prePrint();
    }
}

/** 二叉排序树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 add(BSTNode newNode) {
        if (this.value > newNode.value && this.left == null) {
            this.left = newNode;
            return;
        }
        if (this.value <= newNode.value && this.right == null) {
            this.right = newNode;
            return;
        }
        if (this.value > newNode.value && this.left != null) {
            this.left.add(newNode);
        }
        if (this.value <= newNode.value && this.right != null) {
            this.right.add(newNode);
        }
    }

    public void prePrint() { //前序遍历打印
        System.out.println(this); //先遍历当前自己
        if (this.left != null) {
            this.left.prePrint();
        }
        if (this.right != null) {
            this.right.prePrint();
        }
    }

    //查找节点
    public BSTNode select(int value) {
        if (this.value == value) {
            return this;
        }
        if (this.value > value && this.left != null) {
            return this.left.select(value);
        }
        if (this.value <= value && this.right != null) {
            return this.right.select(value);
        }
        return null;
    }

    //查找某个节点的父节点
    public BSTNode selectParent(int value) {
        if (this.left != null && this.left.value == value) {
            return this;
        }
        if (this.right != null && this.right.value == value) {
            return this;
        }
        if (this.value > value && this.left != null) {
            return this.left.selectParent(value);
        }
        if (this.value < value && this.right != null) {
            return this.right.selectParent(value);
        }
        return null;
    }
 }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@晴天_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值