在二叉搜索树中缓存

时间:2016-02-08 22:19:19

标签: caching binary-search-tree nodes red-black-tree

我有一个程序,我将输入键中的键和位置值输入到红黑树中。如果一个键在输入数组中出现多次,则该键不会再次插入树中;相反,位置值会更新。

例如,对于输入列表S E A R C H T R E E,遇到第一次E,输入并将其位置值存储为1(位置值从0开始);第二次在列表中遇到E时,它不会再次添加到树中;只有它的位置值更新为8.第三次遇到E时,其位置值更新为9。

在整个程序中,我想跟踪已访问的最后一个节点,这样如果输入列表中的下一个键与前一个键相同,我可以在常量时间访问包含该键的节点并修改位置值,而不必通过树并搜索包含该键的节点来修改位置值。它就像一种缓存形式。

这可能吗?

输入是通过put方法完成的。我存储了最后一个输入的密钥,但我不知道如何直接访问包含该密钥的节点而无需搜索树。搜索树将需要一个循环,这不会导致访问节点的持续时间。

public class RedBlackTree<Key extends Comparable, Value> {

    private static final boolean RED = true;
    private static final boolean BLACK = false;
    private Node root;
    private int N; //number of nodes in RBT
    private Key latestKey; //most recently input key

    private class Node{
        private Key key; //key (data stored in node)
        private Value val; //sequence order (whether the key was input first (0), second (1), third (2), etc)
        private Node left, right; //links to left and right subtrees
        private boolean colour; //colour of node
        private int N; //subtree count

        public Node (Key key, Value val, boolean colour, int N){
            this.key = key;
            this.val = val;
            this.colour = colour;
            this.N = N;
        }
    }

    //get sequence order of given key; start searching at root
    public Value get(Key key){
        return get(root, key);
    }

    //get position of given key; start searching at subtree rooted at x
    public Value get(Node x, Key key){
        int cmp;
        while (x != null){
            cmp = key.compareTo(x.key); //compare key being searched for with current key read
            if (cmp < 0){ //key being searched for is smaller than current key
                x = x.left; //go to left child of current key
            }else if (cmp > 0){ //key being searched for is larger than current key
                x = x.right; //go to right child of current key
            }else{ //key being searched for is equal to current key
                return x.val; //return sequence order
            }
        }
        return null; //given key not found
    }

    //insert key-value pair; start at root
    //if key already present, overwrite old value with new value
    //therefore, if a key occurs at several positions in input list, last position is the one saved
    public void put(Key key, Value val){
        if (latestKey != null && (latestKey.compareTo(key) == 0)){
            //how to find the node containing that key?
        }
        root = put(root, key, val);
        root.colour = BLACK;
        latestKey = key;
    }

    //insert key-value pair in subtree rooted at x
    public Node put(Node x, Key key, Value val){
        if (x == null){ //do standard insert, with red link to parent
            N = N + 1;
            return new Node(key, val, RED, 1);
        }
        int cmp = key.compareTo(x.key); //compare key to be inserted with current key read
        if (cmp < 0){ //key to be inserted is smaller than current key
            x.left = put(x.left, key, val); //recursive call to insert key-value pair in subtree rooted at current key's left child
        }else if (cmp > 0){ //key to be inserted is larger
            x.right = put(x.right, key, val); //recursive call to insert key-value pair in subtree rooted at current key's right child
        }else{ //key to be inserted is current key read
            x.val = val; //overwrite value (store last position up to now)
        }

        //fix any right-leaning links
        if (isRed(x.right) && !isRed(x.left)){ //right-leaning red link that needs to be rotated to lean to the left
            x = rotateLeft(x);
        }
        if (isRed(x.left) && isRed(x.left.left)){ //rotate right a node with two left-leaning red links
            x = rotateRight(x);
        }
        if (isRed(x.left) && isRed(x.right)){ //flips colours to pass a red link up the tree (when passing 4-node)
            flipcolours(x);
        }
        x.N = size(x.left) + size(x.right) + 1;
        return x;
    }

    //other methods...
}

1 个答案:

答案 0 :(得分:0)

我将private Key latestKey替换为private Node latest并进行了以下更改。

public void put(Key key, Value val){
    if ((latest != null) && (latest.key.compareTo(key) == 0)){
        latest.val = val;
        return;
    }
    root = put(root, key, val);
    root.colour = BLACK;
}

public Node put(Node x, Key key, Value val){
    if (x == null){
        N = N + 1;
        latest = new Node(key, val, RED, 1);
        return latest;
    }
    if (x != null){
        latest = x;
    }
    int cmp = key.compareTo(x.key); //compare key to be inserted with current key read
    //etc
}