符号表:二叉查找树的简单学习

所有学习内容全部来自于《算法》第四版

简单概述

二叉查找树是符号表的一种实现。
符号表,又称为字典,或者索引之类的。主要目的就是讲一个键和一个值联系起来,能够通过键增删改查等操作。
符号表有二叉查找树、红黑树以及散列表的实现。基于这些算法,能够扩展出很多应该用。

符号表API定义

主要实现如下方法:
key的话需要继承于Comparable。
public interface SymbolTable<Key extends Comparable<Key>,Value> {
    Value get(Key key);
    void put(Key key,Value value);
    void delete(Key key);
    Key max();
    Key min();
    int size();
    boolean isEmpty();
    boolean contains(Key key);

    /**
     * 小于等于key的最大键,向下取整。
     * @param key
     * @return
     */
    Key floor(Key key);

    /**
     * 大于等于key的最小键,向上取整。
     * @param key
     * @return
     */
    Key ceiling(Key key);

    /**
     * 小于key的数量
     * @param key
     * @return
     */
    int rank(Key key);

    /**
     * 排名为k的键,即树中刚好有k个小于它的键,
     * 那么实际上排名应该是k+1
     * @param k
     * @return
     */
    Key select(int k);

    void deleteMax();
    void deleteMin();

    /**
     * [lo,hi]之间的键的数量
     * @param lo
     * @param hi
     * @return
     */
    int size(Key lo,Key hi);

    /**
     * [lo,hi]之间的所有的键,已经排序。
     * @param lo
     * @param hi
     * @return
     */
    Iterable<Key> keys(Key lo,Key hi);


    /**
     * 表中所有键的集合,已经排序。
     * @return
     */
    Iterable<Key> keys();
}

抽象符号表

接口里面有一些方法的实现可以依赖于其它方法。子类不需要进一步实现,如下:

public abstract class AbstractSymbolTable<Key extends Comparable<Key>,Value> implements SymbolTable<Key,Value>{
    public boolean contains(Key key) {
        return null!=get(key);
    }

    public boolean isEmpty() {
        return size()==0;
    }
    
    public Iterable<Key> keys() {
        return keys(min(),max());
    }

    public int size(Key lo, Key hi) {
        if (lo.compareTo(hi)>0)
            return 0;
        else if (contains(hi))
            return rank(hi)-rank(lo)+1;
        else
            return rank(hi)-rank(lo);
    }
}

二叉查找树的算法详解

在这里插入图片描述

二叉查找树的具体实现

所有的实现都用的递归,如下:

public class BST<Key extends Comparable<Key>,Value> extends AbstractSymbolTable<Key,Value>{

    public static void main(String[] args) {
        BST<Integer,Integer> bst=new BST<Integer,Integer>();
        bst.put(1,3);
        bst.put(2,2);
        bst.put(3,1);
        System.out.println(bst.toString());
        System.out.println(bst.size());
        System.out.println(bst.select(1));
        System.out.println(bst.select(0));

    }
    private class Node{
        private Key key;
        private Value value;
        private Node left,right;
        private int n;

        public Node(Key key, Value value, int n) {
            this.key = key;
            this.value = value;
            this.n = n;
        }

        @Override
        public String toString() {
            return "(key:"+key+"  value:"+value+") ";
        }
    }

    private Node root;

    @Override
    public String toString() {
        return toString(root);
    }

    private String toString(Node node){
        if (node==null) return "";
        return toString(node.left)+node.toString()+toString(node.right);
    }

    public int size(){
        return size(root);
    }

    private int size(Node node){
        if (node==null) return 0;
        return size(node.left)+size(node.right)+1;
    }

    public Value get(Key key){
        return get(root,key);
    }

    private Value get(Node node,Key key){
        if (node==null) return null;
        int temp=node.key.compareTo(key);
        if (temp==0) return node.value;
        else if (node.key.compareTo(key)<0) return get(node.right,key);
        else return get(node.left,key);
    }

    public void put(Key key,Value value){
        root=put(root,key,value);
    }

    private Node put(Node node,Key key,Value value){
        if (node==null) return new Node(key,value,1);
        int temp=key.compareTo(node.key);
        if (temp==0)        node.value=value;
        else if (temp>0)    node.right=put(node.right,key,value);
        else                node.left=put(node.left,key,value);
        node.n=size(node.left)+size(node.right)+1;
        return node;
    }

    public void delete(Key key){
        root=delete(root,key);
    }

    public Node delete(Node node,Key key){
        if (node==null) return null;
        int result=node.key.compareTo(key);
        if      (result<0) node.right=delete(node.right,key);
        else if (result>0) node.left=delete(node.left,key);
        else{
            if (node.left==null)  return node.right;
            if (node.right==null) return node.left;
            Node temp=node;
            Node replaceNode=min(node.right);
            node=replaceNode;
            node.right=deleteMin(temp);
            node.left=temp.left;
        }
        node.n=size(node.left)+size(node.right)+1;
        return node;
    }

    public Key max() {
        return max(root).key;
    }
    private Node max(Node node) {
        if(node.right==null) return node;
        else return max(node.right);
    }

    public Key min() {
        return min(root).key;
    }

    private Node min(Node node) {
        if(node.left==null) return node;
        else return min(node.left);
    }

    public boolean contains(Key key){
        return false;
    }

    public Key floor(Key key) {
        Node x=floor(root,key);
        if (x!=null) return x.key;
        else return null;
    }

    private Node floor(Node node,Key key){
        if (node ==null) return null;
        int result=node.key.compareTo(key);
        if (result==0) return node;
        if (result>0)  return floor(node.left,key);
        Node rightNode=floor(node.right,key);
        if (rightNode!=null) return rightNode;
        else return node;
    }

    public Key ceiling(Key key) {
        Node x=ceiling(root,key);
        if (x!=null) return x.key;
        else return null;
    }

    private Node ceiling(Node node,Key key) {
        if (node==null) return null;
        int result=node.key.compareTo(key);
        if (result==0) return node;
        if (result<0) return ceiling(node.right,key);
        Node leftNode=floor(node.left,key);
        if (leftNode!=null) return leftNode;
        else return node;
    }

    public int rank(Key key) {
        return rank(root,key);
    }

    public int rank(Node node,Key key) {
        if (node==null) return 0;
        int result=node.key.compareTo(key);
        if      (result>0) return rank(node.left,key);
        else if (result<0) return size(node.left)+1+rank(node.right,key);
        else               return size(node.left);
    }

    public Key select(int k) {
        Node x=select(root,k);
        if (x!=null) return x.key;
        else return null;
    }

    public void deleteMax() {
        root=deleteMax(root);
    }

    private Node deleteMax(Node node) {
        if (node.right==null) return node.left;
        node.right=deleteMax(node.right);
        node.n=size(node.left)+size(node.right)+1;
        return node;
    }

    public void deleteMin() {
        root=deleteMin(root);
    }

    private Node deleteMin(Node node) {
        if (node.left==null) return node.right;
        node.left=deleteMin(node.left);
        node.n=size(node.left)+size(node.right)+1;
        return node;
    }

    public Node select(Node node,int k) {
        if (node==null) return null;
        int t=size(node.left);
        if (t>k) return select(node.left,k);
        if (t==k) return node;
        return select(node.right,k-t-1);
    }

    public Iterable<Key> keys(Key lo, Key hi) {
        return null;
    }
}

猜你喜欢

转载自blog.csdn.net/ywg_1994/article/details/100639193