[Loj.ac-java] Binary Search Tree - 二分搜索树

问题:

说明:

https://oi-wiki.org/ds/bst/

来 写 一 个 BST。

问题链接:https://loj.ac/problem/104

提交记录:

https://loj.ac/submission/889961

输入案例:

传了一份测试数据:https://download.csdn.net/download/qq_28033719/12609664 (假装骗积分)


我的代码:

准备知识

1、以往知识:

左旋转 右旋转 前驱 后继 https://blog.csdn.net/qq_28033719/article/details/107316144

2、二叉搜索树:

把二分法玩的飞起的树,后来红黑树也基于这个来玩。

3、插入

没有单双旋,只是找到位置插入就行,不过因为 AVL 反而是基于这个来搞得,所以先写个 BST 模板

具体代码

因为 Splay 、 Treap 都玩过了,所以这个可以默写一次,不过还是有点错。

import java.util.Scanner;

public class BST {
    class Node {
        int val;
        Node left;
        Node right;
        int num;
        int size;
        Node(int val) {
            this.val = val;
            this.num = 1;
        }
    }

    Node root;

    public void pushup(Node r) {
        if(r == null) return;
        int left = r.left == null ? 0 : r.left.size;
        int right = r.right == null ? 0 : r.right.size;
        r.size = left + right + r.num;
    }

    public Node insert(Node r, int v) {
        if(r == null) r = new Node(v);
        else if(r.val == v) r.num ++;
        else if(r.val > v) r.left = insert(r.left, v);
        else r.right = insert(r.right, v);
        pushup(r);
        return r;
    }

    public void clear(Node r) {
        if(r != null) {
            r.left = null;
            r.right = null;
        }
    }

    public Node delete(Node r, int v) {
        if(r == null) return r;
        else if(r.val < v) r.right = delete(r.right, v);
        else if(r.val > v) r.left = delete(r.left, v);
        else {
            r.num --;
            if(r.num == 0) {
                boolean ln = r.left == null;
                boolean rn = r.right == null;
                if(ln && rn) return null;
                else if(ln) {
                    Node res = r.right;
                    clear(r);
                    return res;
                }
                else if(rn) {
                    Node res = r.left;
                    clear(r);
                    return res;
                }
                else {
                    Node res = deletemin(r.left);
                    res.left = res.val == r.left.val ? r.left.left : r.left;
                    res.right = r.right;
                    clear(r);
                    pushup(res);
                    return res;
                }
            }
        }
        pushup(r);
        return r;
    }

    public Node deletemin(Node r) {
        if(r.right == null) return r;
        else {
            Node res = deletemin(r.right);
            // 这里需要把找到的左边最大值拿回来,要小心它还有个 left
            if(r.right.val == res.val) r.right = res.left;
            r.size -= res.num;
            return res;
        }
    }


    public int find(Node r, int n) {
        if(r == null) return 0;
        // 只弄个 r.left ,加上了 r.num 值,排名上 r.num 在判断中出错
        int left = r.left == null ? 0 : r.left.size;
        if(left >= n) return find(r.left, n);
        else if(n > left + r.num) return find(r.right, n - left - r.num);
        return r.val;
    }

    public int rank(Node r, int v) {
        if(r == null) return Integer.MIN_VALUE;
        else if(r.val > v) return rank(r.left, v);
        else if(r.val < v) return r.num + rank(r.right, v) + (r.left == null ? 0 : r.left.size);
        else return r.left == null ? 1 : r.left.size + 1;
    }

    public int pre(Node r, int v) {
        if(r == null) return Integer.MIN_VALUE;
        else if(r.val >= v) return pre(r.left, v);
        else return Math.max(r.val, pre(r.right, v));
    }

    public int sub(Node r, int v) {
        if(r == null) return Integer.MAX_VALUE;
        else if(r.val <= v) return sub(r.right, v);
        else return Math.min(r.val, sub(r.left, v));
    }

    public Node findMax(Node r) {
        if(r == null || r.right == null) return r;
        else return findMax(r.right);
    }

    public Node findMin(Node r) {
        if(r == null || r.left == null) return r;
        else return findMin(r.left);
    }

    public static void main(String[] args) {
        BST tree = new BST();
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        while(n -- > 0) {
            int op = sc.nextInt();
            int v = sc.nextInt();
            switch (op) {
                case 1 : tree.root = tree.insert(tree.root, v);break;
                case 2 : tree.root = tree.delete(tree.root, v);break;
                case 3 : System.out.println(tree.rank(tree.root, v));break;
                case 4 : System.out.println(tree.find(tree.root, v));break;
                case 5 : System.out.println(tree.pre(tree.root, v));break;
                case 6 : System.out.println(tree.sub(tree.root, v));break;
                case 7 :
                    Node max = tree.findMax(tree.root);
                    System.out.println(max == null ? 0 : max.val); break;
                case 8 :
                    Node min = tree.findMin(tree.root);
                    System.out.println(min == null ? 0 : min.val); break;
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_28033719/article/details/107769968
今日推荐