BST

/*基于二叉查找树的符号表*/
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);
    }
    private int size(Node x) {
        if (x == null) {
            return 0;
        }
        return x.n;
    }

    //  二叉查找树的查找和排序方法的实现
    public Value get(Key key) {
        return get(root, key);
    }
    public Value get(Node x, Key key) {
        //  如果找不到则返回null
        if (x == null) {
            return null;
        }
        int cmp = key.compareTo(x.key);
        if (cmp > 0) {
            return get(x.right, key);
        }else if (cmp < 0) {
            return get(x.left, key);
        }else {
            return x.val;
        }
    }

    public void put(Key key, Value val) {
        //  查找key,找到则更新它的值,否则为它创建一个新的结点
        root = put(root, key, val);
    }
    private Node put(Node x, Key key, Value val) {
        if (x == null) {
            return new Node(key, val, 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;
    }
    private Node min(Node x) {
        if (x.left == null) {
            return x;
        }
        return min(x.left);
    }

    //  最大键
    public Key max() {
        return max(root).key;
    }
    private Node max(Node x) {
        if (x.right == null) {
            return x;
        }
        return max(x.right);
    }

    //  向下取整
    public Key floor(Key key) {
        Node x = floor(root, key);
        if (x == null) {
            return null;
        }
        return x.key;
    }
    private Node floor(Node x, Key key) {
        if (x == null) {
            return null;
        }
        int cmp = key.compareTo(x.key);
        if (cmp == 0) {
            return x;
        }
        if (cmp < 0) {
            return floor(x.left, key);
        }
        Node t = floor(x.right, key);
        if (t != null) {
            return t;
        }else {
            return x;
        }
    }

    //  找到排名为k的键(即树中正好有k个小于它的键)
    public Key select(int k) {
        return select(root, k).key;
    }
    private Node select(Node x, int k) {
        //  返回排名为k的节点
        if (x == null) {
            return null;
        }
        int t = size(x.left);
        if (t > k) {
            return select(x.left, k);
        }else if (t < k) {
            return select(x.right, k-t-1);
        }else {
            return x;
        }
    }

    //  计算给定键的排名
    public int rank(Key key) {
        return rank(key, root);
    }
    private int rank(Key key, Node x) {
        //  返回以x为根节点的子树中小于x.key的键的数量
        if (x == null) {
            return 0;
        }
        int cmp = key.compareTo(x.key);
        if (cmp < 0) {
            return rank(key, x.left);
        }else if (cmp > 0) {
            return 1 + size(x.left) + rank(key, x.right);
        }else {
            return size(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;
            }
            if (x.left == null) {
                return x.right;
            }
            //  将需要删除的链接保存下来
            Node t = x;
            //  将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;
    }

    //  二叉查找树的范围查找操作
    public Iterable<Key> keys() {
        return keys(min(), max());
    }
    public Iterable<Key> keys(Key lo, Key hi) {
        Queue<Key> queue = new Queue<>();
        keys(root, queue, lo, hi);
        return queue;
    }
    private void keys(Node x, Queue<Key> queue, Key lo, Key hi) {
        if (x == null) {
            return;
        }
        int cmplo = lo.compareTo(x.key);
        int cmphi = hi.compareTo(x.key);
        if (cmplo < 0) {
            keys(x.left, queue, lo, hi);
        }
        if (cmplo <= 0 && cmphi >= 0) {
            queue.enqueue(x.key);
        }
        if (cmphi > 0) {
            keys(x.right, queue, lo, hi);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值