算法 一书中,先介绍2-3查找树,随后利用红黑树对其进行实现(红链接连接两个2-节点形成3-节点,而黑链接则是2-3查找树中的普通链接),类中主要定义了三种方法,左旋,右旋和变色(何时左旋,右旋或者变色书中介绍的很详细),利用put方法实现递归,不断地将元素注入到红黑树中
(我对put方法中的递归的理解为:可将put方法看做有很多个put方法,当前的put方法在调用另一个put方法,另一个put方法又在调用下一个一模一样的put方法,最后一个被调用的put方法在判断h为null时
(相关代码为:
if (h==null)
return new Node(key,value,1,RED);
)
返回了一个Node,
即put--put--put--put(倒数第二个put方法)--put(最后一个put方法)
随后不断地从倒数第二个put方法不断依次往前执行相应的put方法,每次执行put方法时都会旋转或者变色,正因如此,才会出现在插入一个元素时,元素沉入底层后,进行了变色,随后又进行了旋转等连锁反应)
其实红黑树和二叉排序树很像(或者说是特殊的二叉排序树),所以和二叉排序树一样定义了N来表示节点数,RedBlackBST <Key extends Comparable<Key>,Value>利用了泛型,如果在使用该树时是
RedBlackBST <Integer,Integer> derder =new RedBlackBST <Integer,Integer>();
integer派生了Comparable接口,并提供了一个实现,该方法调用了compare()方法,利用三目表达式,在大于和小于时返回+1和-1,等于时返回0。
故该类中的if (cmp<0)等皆源于此。
public class RedBlackBST <Key extends Comparable<Key>,Value> {
private Node root;
private static final boolean RED = true;
private static final boolean BLACK = false;
private class Node {
Key key;
Value value;
Node left, right;
int N;
boolean color;
public Node(Key key, Value value, int n, boolean color) {
this.key = key;
this.value = value;
N = n;
this.color = color;
}
}
boolean isRed(Node x) {
if (x == null) return false;
return x.color == RED;
}
private Node rotateLeft(Node h){
Node x=h.right;
h.right=x.left;
x.left=h;
x.color=h.color;
h.color=RED;
x.N=h.N;
h.N=1+size(h.left)+size(h.right);
return x;
}
private Node rotateRight(Node h){
Node x=h.left;
h.left=x.right;
x.right=h;
x.color=h.color;
h.color=RED;
x.N=h.N;
h.N=1+size(h.left)+size(h.right);
return x;
}
private void filpColors(Node h){
h.color=RED;
h.left.color=BLACK;
h.right.color=BLACK;
}
private int size() {
return size(root);
}
private int size(Node x) {
if (x == null) return 0;
else return x.N;
}
public void put(Key key,Value value){
root=put(root,key,value);
root.color=BLACK;
}
private Node put(Node h,Key key,Value value){
if (h==null)
return new Node(key,value,1,RED);
int cmp=key.compareTo(h.key);
if (cmp<0) h.left=put(h.left,key,value);
else if (cmp>0) h.right=put(h.right,key,value);
else h.value=value;
if (isRed(h.right)&&!isRed(h.left)) h=rotateLeft(h);
if (isRed(h.left)&&isRed(h.left.left)) h=rotateRight(h);
if (isRed(h.left)&&isRed(h.right)) filpColors(h);
h.N=size(h.left)+size(h.right)+1;
return h;
}
}