下面的代码实现了对红黑树的元素的添加和查找,想要了解和掌握,就要先理解2-3树的思想.红黑二叉查找树的思想是用将3-结点表示为由一条左斜的红色链接(两个2-结点其中之一是另一个左子结点)相连的两个2-结点,而且,我们无需修改就可以直接使用标准二叉查找树的表示方法
package cn.edu.zzuli.api;
import cn.edu.zzuli.api.BST;
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
public class RedBlackBST<Key extends Comparable<Key>, Value>{
private static final boolean RED = true;
private static final boolean BLACK = false;
private Node root;
private class Node{
Key key;//键
Value val;//相关联的值
int N;//这棵子树中的结点总数
Node left, right;//左右子树
boolean color;//由其父结点指向它的链接的颜色
public Node(Key key, Value val, int N, boolean color) {
this.key = key;
this.val = val;
this.N = N;
this.color = color;
}
}
//如果指向它的链接是红色的,那么该变量为true,黑色则为false.
//约定空链接为黑色
private boolean isRed(Node h) {
if(h == null)
return false;
return h.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 flipColors1(Node h) {
h.color = RED;
h.left.color = BLACK;
h.right.color = BLACK;
}
//这棵子树中的结点总数
public 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 val) {
//查找key,找到则更新其值,否则为它新建一个结点
root = put(root, key, val);
//每次插入后都会将根结点设为黑色
root.color = BLACK;
}
private Node put(Node h, Key key, Value val) {
if(h == null)//标准的插入操作,和父结点用红链接相连
return new Node(key, val, 1, RED);
int cmp = key.compareTo(h.key);
if(cmp < 0) {
h.left = put(h.left, key, val);
}else if(cmp > 0) {
h.right = put(h.right, key, val);
}else {
h.val = val;
}
//如果右子结点是红色的而左子结点是黑色的,进行左旋转
if(!isRed(h.left) && isRed(h.right)) {
h = rotateLeft(h);
}
//如果左子结点是红色的且它的左子结点也是红色的,进行右旋转
if(isRed(h.left) && isRed(h.left.left)) {
h = rotateRight(h);
}
//如果左右子结点均为红色,进行颜色转换
if(isRed(h.left) && isRed(h.right)) {
flipColors1(h);
}
h.N = 1 + size(h.left) + size(h.right);
return h;
}
public Value get(Key key) {
return get(root, key).val;
}
private Node get(Node h, Key key) {
if(h == null)
return null;
int cmp = key.compareTo(h.key);
if(cmp < 0) {
return get(h.left, key);
}else if(cmp > 0) {
return get(h.right, key);
}
return h;
}
public static void main(String[] args) {
RedBlackBST<String, Integer> st = new RedBlackBST<String, Integer>();
for (int i = 0; !StdIn.isEmpty(); i++) {
String key = StdIn.readString();
st.put(key, i);
}
//for (String s : st.keys())
StdOut.println(st.get("A"));
StdOut.println();
}
}