二叉查找树 Java代码

参考:《算法第四版》

代码

public class BST<Key extends Comparable<Key>,Value>{
    private Node root;//二叉查找树的根节点
    private class Node{
        private Key key;//键
        private Value val;//值
        private Node left,right;//指向子树的链接
        private int N;//以该节点为根的子树中的节点总数
        public Node(Key key,Value val,int N){
            this.key=key;
            this.val=val;
            this.N=N;
        }
    }
    public int size(){
        return size(root);
    }
    public int size(Node x){
        if(x==null)
            return 0;
        else
            return x.N;
    }
    public Value get(Key key){
        return get(root,key);
    }
    //在以x为根节点的子树中查找并返回Key对应的值
    //找不到则返回Null
    private Value get(Node x,Key key){
        if(x==null)
            return null;
        int cmp=key.compareTo(x.key);
        if(cmp<0)
            return get(x.left,key);
        else if(cmp>0)
            return get(x.right,key);
        else
            return x.val;
    }

    public void put(Key key,Value val){
        root=put(root,key,val);
        //查找Key,找到则更新它的值,否则为他创建一个新的节点
    }
    private Node put(Node x,Key key,Value val){
        //如果key存在于以x为根节点的子树中则更新它的值
        //否则将以Key和val为键值对的新结点插入到该子树中
        if(x==null)
            return new Node(key,val,1);//设为根节点,节点总数为1
        int cmp=key.compareTo(x.key);
        if(cmp<0)
            x.left=put(x.left,key,val);
        else if(cmp>0)
            x.right=put(x.right,key,val);
        else
            x.val=val;
        x.N=size(x.left)+size(x.right)+1;
        return x;
    }
    //最小键
    public Key min(){
        return min(root).key;
    }
    public Node min(Node x){
        if(x.left==null)
            return x;
        return min(x.left);
    }
    //删除最小键
    //要不断深入根节点左子树中直至遇见一个空链接
    public void deleteMin(){
        root=deleteMin(root);
    }
    private Node deleteMin(Node x){
        if(x.left==null)
            return x.right;
        x.left=deleteMin(x.left);
        x.N=size(x.left)+size(x.right)+1;
        return x;
    }
    public void delete(Key key){
        root=delete(root,key);
    }
    private Node delete(Node x,Key key){
        if(x==null)
            return null;
        int cmp=key.compareTo(x.key);
        if(cmp<0)
            x.left=delete(x.left,key);
        else if(cmp>0)
            x.right=delete(x.right,key);
        else{//这个节点就是要删除的节点
            if(x.right==null)
                return x.left;//右子树为空,删除了x就只剩左子树,直接返回左子树
            if(x.left==null)
                return x.right;//左子树为空。。
            Node t=x;//要删除的原节点
            x=min(t.right);//后继节点
            x.right=deleteMin(t.right);//后继节点的右子树=删除了它的 原节点右子树
            x.left=t.left;//后继节点的左子树=原节点的左子树
        }
        x.N=size(x.left)+size(x.right)+1;
        return x;
    }
}

插入

如果树是空的,就返回一个含有该键值对的新结点。
如果被查找的键小于根节点的键,我们会继续在左子树中插入该键,否则在右子树中插入该键。
在这里插入图片描述

删除

怎样删除一个拥有两个子节点的节点?
在删除节点x后用它的后继节点填补它的位置。因为x有一个右子节点,因此它的后继节点就是其右子树中的最小节点。
用4个步骤完成将x替换为它的后继节点的任务:
1.将指向即将被删除的节点的链接保存为t。
2.将x指向它的后继节点min(r.right)
3.将x的右链接(原本指向一颗所有节点都大于x.key的二叉查找树)指向deleteMin(t.right),也就是在删除后所有节点仍然都大于x.key的子二叉查找树。
4.将x的左链接(本为空)设为t.left(其下所有的键都小于被删除的节点和它的后继节点)。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值