我有一个程序,我将输入键中的键和位置值输入到红黑树中。如果一个键在输入数组中出现多次,则该键不会再次插入树中;相反,位置值会更新。
例如,对于输入列表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...
}
答案 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
}