|
1090 | 1090 | ->没有任何一个结点同时和两条红链接相连。
|
1091 | 1091 | ->该树是完美黑色平衡的,即任意空链接到根结点的路径上的黑链接数量相同。
|
1092 | 1092 | 实现:ca.mcmaster.chapter.three.rbtree.RedBlackBST<K, V>
|
1093 |
| - public class RedBlackBST<K, V> { |
| 1093 | + public class RedBlackBST<K extends Comparable<K>, V> { |
1094 | 1094 | private Node root;
|
1095 | 1095 | public static final Boolean RED = true;
|
1096 | 1096 | public static final Boolean BLACK = false;
|
|
1113 | 1113 | return node.color == RED;
|
1114 | 1114 | }
|
1115 | 1115 |
|
1116 |
| - public Node rotateLeft(Node node){ //将右侧的红链接与左链接(黑链接)交换 |
1117 |
| - Node temp = node.right; //思考:如果将原父结点作为temp需要4条赋值语句,所以通过将右结点作为中间变量可以减少开销。 |
| 1116 | + public Node rotateLeft(Node node){ |
| 1117 | + Node temp = node.right; |
1118 | 1118 | node.right = temp.left;
|
1119 | 1119 | temp.left = node;
|
1120 | 1120 | temp.color = node.color;
|
|
1123 | 1123 | node.N = 1 + size(node.left) + size(node.right);
|
1124 | 1124 | return temp;
|
1125 | 1125 | }
|
1126 |
| - public Node rotateRight(Node node){ //将左侧的红链接与右链接(黑链接)交换 |
1127 |
| - Node temp = node.left; |
| 1126 | + public Node rotateRight(Node node){ |
| 1127 | + Node temp = node.left; |
1128 | 1128 | node.left = temp.right;
|
1129 | 1129 | temp.right = node;
|
1130 | 1130 | temp.color = node.color;
|
|
1137 | 1137 | if(null == node) return 0;
|
1138 | 1138 | return node.N;
|
1139 | 1139 | }
|
| 1140 | + public void filpColor(Node node){ |
| 1141 | + node.color = RED; |
| 1142 | + node.left.color = BLACK; |
| 1143 | + node.right.color = BLACK; |
| 1144 | + } |
| 1145 | + public void put(K k, V v){ |
| 1146 | + root = put(root, k, v); |
| 1147 | + root.color = BLACK; |
| 1148 | + } |
| 1149 | + public Node put(Node node, K k, V v){ |
| 1150 | + if(node == null){ return new Node(k, v, 1, RED) ; } |
| 1151 | + int cmp = k.compareTo(node.k); |
| 1152 | + if(cmp < 0) return put(node.left, k, v); |
| 1153 | + else if(cmp > 0) return put(node.right, k, v); |
| 1154 | + else node.v = v; |
| 1155 | + if(isRed(node.right) && !isRed(node.left)) node = rotateLeft(node); |
| 1156 | + if(isRed(node.left) && isRed(node.left.left)) node = rotateRight(node); |
| 1157 | + if(isRed(node.left) && isRed(node.left.left)) filpColor(node); |
| 1158 | + node.N = size(node.left) + size(node.right) + 1; |
| 1159 | + return node; |
| 1160 | + } |
1140 | 1161 | }
|
1141 | 1162 |
|
1142 | 1163 | 4.颜色转换:
|
1143 | 1164 | ->两个子链接都是红链接,那么我们可以将父结点向上的链接变成红链接,将两个子链接变成黑链接。
|
1144 | 1165 | 实现:ca.mcmaster.chapter.three.rbtree.RedBlackBST#filpColor(Node)
|
1145 | 1166 | ->根节点总是黑色的,根据上一条,我们总是会将根节点设置为红链接,但是我们要将父结点设置成黑链接,每次由红色变成黑色树的黑链接高度增加1.
|
| 1167 | + |
| 1168 | + 5.将红链接在树中向上传递: |
| 1169 | + ->如果右结点是红色而左子结点是黑色,进行左旋转。 |
| 1170 | + ->如果左子结点是红色而且他的左子结点也是红色的,进行右旋转。 |
| 1171 | + ->如果左右子结点均是红色,颜色转换。 |
| 1172 | + public Node put(Node node, K k, V v){ |
| 1173 | + if(node == null){ return new Node(k, v, 1, RED) ; } |
| 1174 | + int cmp = k.compareTo(node.k); //对键向左右子结点进行比较,向左向右递归调用,直到找到了合适的结点。 |
| 1175 | + if(cmp < 0) return put(node.left, k, v); |
| 1176 | + else if(cmp > 0) return put(node.right, k, v); |
| 1177 | + else node.v = v; |
| 1178 | + if(isRed(node.right) && !isRed(node.left)) node = rotateLeft(node); //如果右结点是红色而左子结点是黑色,进行左旋转。 |
| 1179 | + if(isRed(node.left) && isRed(node.left.left)) node = rotateRight(node); //如果左子结点是红色而且他的左子结点也是红色的,进行右旋转。 |
| 1180 | + if(isRed(node.left) && isRed(node.left.left)) filpColor(node); //如果左右子结点均是红色,颜色转换。 |
| 1181 | + node.N = size(node.left) + size(node.right) + 1; |
| 1182 | + return node; |
| 1183 | + } |
1146 | 1184 |
|
1147 | 1185 |
|
1148 | 1186 |
|
|
0 commit comments