BST二叉检索树(Java)

目录

结点类

插入

删除

寻找最小值

删除最小值并返回其父结点

删除结点

查找

计算深度

中序遍历(由小到大输出二叉检索树)


首先需要定义一个结点类

结点类

public class BinNode<K,V> {
    public K key;
    public V value;
    private BinNode<K,V> left;
    private BinNode<K,V> right;
    public BinNode(K key,V value){
        this.key=key;
        this.value=value;
    }
    public BinNode<K, V> getLeft() {
        return left;
    }
    public void setLeft(BinNode<K, V> left) {
        this.left = left;
    }
    public BinNode<K,V> getRight() {
        return right;
    }
    public void setRight(BinNode<K,V> right) {
        this.right = right;
    }
}

再定义一个BST接口,逐个实现接口中的方法

插入

根节点空插入根节点,等于更新value,小于找左子树,大于找右子树

    public void insert(String key, String value) {
        if(root==null){
            root=new BinNode<>(key, value);
            return;
        }
        BinNode<String,String>cur=root,tmp=new BinNode<>(key, value);
        while (cur!=null)
            if (cur.value.compareTo(value)<0){
                if (cur.getRight()==null){
                    cur.setRight(tmp);
                    return;
                }
                cur=cur.getRight();
            }
            else if(cur.value.compareTo(value)>0){
                if (cur.getLeft()==null){
                    cur.setLeft(tmp);
                    return;
                }
                cur=cur.getLeft();
            }
            else cur.value=value;
    }

删除

三种情况,但前两种可以当成第三种处理

为叶结点:直接将指向其的指针置为null

有一个子结点:直接将指向其的指针置为该子结点

有两个子结点:找到待删结点左子树的最大结点或右子树的最小结点(寻找最小值),将待删结点值替换为找到的结点,并删除原本找到的结点(删除最小值)。

这里需要两个额外的方法:寻找最小值删除最小值

寻找最小值

一直递归找左子结点直到左子结点为空,说明找到最小结点,返回。

private BinNode getMin(BinNode root){
        if (root.getLeft()==null)return root;
        else return getMin(root.getLeft());
    }

删除最小值并返回其父结点

一直递归找左子结点直到左子结点为空,说明找到最小结点,返回右子结点(可以是null),此时的root是最小结点的父结点,此时的实参是最小结点的右结点(如果不为null则一定小于root)。

实参赋给root的左子结点,相当于删除最小结点但保留其子结点。

private BinNode deleteMin(BinNode root){
        if (root.getLeft()==null)//左子树为空,说明找到最小结点,返回右子树(可以是null)
            return root.getRight();
        else{
            //一直找左子树直到找到,此时的root是最小结点的父结点
            // 此时的实参是最小结点的右结点(如果不为null则一定小于root)
            // 将实参赋给root的左子结点,相当于删除最小结点但保留其子结点
            root.setLeft(deleteMin(root.getLeft()));
            return root;
        }
    }

删除结点

public String remove(String key) {
        return removeHelp(root,key).value;
    }
private BinNode<String,String> removeHelp(BinNode<String,String>root,String key){
        if (root==null)return null;
        //查找待删除结点
        if (root.key.compareTo(key)>0)root.setLeft(removeHelp(root.getLeft(),key));
        else if (root.key.compareTo(key)<0)root.setRight(removeHelp(root.getRight(),key));
        //找到该结点
        else {
            if(root.getLeft()==null)root=root.getRight();
            else if(root.getRight()==null)root=root.getLeft();
            else {
                BinNode<String,String> tmp=getMin(root.getRight());//找到右子树上的最小结点
                root.key=tmp.key;root.value=tmp.value;//将待删结点信息替换为最小结点的信息
                root.setRight(deleteMin(root.getRight()));//删除右子树上的最小结点
            }
        }
        return root;
    }

查找

等于返回,小于找左子树,大于找右子树,为空则没有找到

public String search(String key) {
        BinNode<String,String> curr=root;
        while(curr!=null){
            if (Objects.equals(key, curr.key))return curr.value;
            else if (key.compareTo(curr.key)<0)curr= curr.getLeft();
            else curr= curr.getRight();
        }
        return null;
    }

计算深度

通过递归求左右子树深度最大值

private int getHeight(BinNode root){
        if (root==null)return 0;
        int h1=0,h2=0;
        h1=getHeight(root.getLeft());
        h2=getHeight(root.getRight());
        if (h1>h2)return h1+1;
        else return h2+1;
    }

中序遍历(由小到大输出二叉检索树)

先遍历左子树,然后访问根结点,最后遍历右子树。

先访问根结点的左子节点,直到为空,就可以输出第一个结点,此结点视为根结点,下一步访问其右子结点。对于以其右子结点为根的右子树进行中序遍历,即递归调用该方法。右子树遍历完之后,回退到第一个输出结点的父结点并将其输出,再对该父结点的右子树进行中序遍历,如此往复。

public void inorderTraversal(BinNode root){
        if (root==null)return;
        inorderTraversal(root.getLeft());
        System.out.println("["+root.key+"---<"+root.value+">]");
        inorderTraversal(root.getRight());
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值