二叉查找树

二叉查找树的基本储存单位是节点,每个节点包含:
1. 键,用来识别和排序一个节点。(如:一个单词)
2. 值,是键的附属信息。(如:单词的定义,发音等信息)
3. 左子树和右子树。

用途:可以根据键查找到相应的值。

二叉查找树是一棵二叉树,但是多了两个限制条件:
1. 每个节点都含有一个可排序的键(以及相关联的值)。
2. 每个节点的键都大于其左子树的任意节点,并小于右子树的任意节点。

优势:把链表插入的灵活性和二分查找的高效性结合起来。

PS:此处暂不考虑键相等问题。若要考虑,可把键相等节点归于左或右任意子树,或者在每个节点存储一个count记录个数。

节点
 private class Node{
        private Key key;
        private Value val;
        private Node left, right;
        private int N;

        public Node(Key key, Value val){
            this.key = key;
            this.val = val;
        }
    }
添加
 public Node put(Key key, Value val){
        Node node = new Node(key, val);
        Node tem = root;
        if (root == null){
            return root = node;
        }
        while (tem != null){
            int cmp = key.compareTo(tem.key);
            if (cmp < 0 ) {
                if (tem.left == null) return tem.left = node;
                tem = tem.left;
            }
            else if (cmp > 0){
                if (tem.right == null) return tem.right = node;
                tem = tem.right;
            }
            else {
                tem.val = val;
                break;
            }
        }
        return node;
    }
查询
 public Value get(Key key){
        Node tem = root;
        while (tem != null){
            int cmp = key.compareTo(root.key);
            if (cmp < 0) tem = tem.left;
            else if (cmp > 0) tem = tem.right;
            else return tem.val;
        }
        return null;
    }
删除
 public boolean delete(Key key){
        Node ans = delete(root, key);
        if (ans == null && root != null && (root.left != null || root.right != null)) return false;
        root = ans;
        return true;
    }
    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;
            while (x.left != null) x = x.left;
            x.left = t.left;
            x.right = deleteMin(t.right);
        }
        return x;
    }

    private Node deleteMin(Node x){
        if (x.left == null) return x.right;
        x.left = deleteMin(x.left);
        return x;
    }
升序打印
//中序遍历
    public void show(){
        Stack<Node> stack = new Stack();
        Node tem = root;
        while (tem != null || !stack.isEmpty()){
            while (tem != null){
                stack.push(tem);
                tem = tem.left;
            }
            tem = stack.pop();
            System.out.print(tem.key + " ");
            tem = tem.right;
        }
    }

问题:可能会出现极不平衡的树,效率会很低。

点赞