Skip to content

Commit 9e4ed76

Browse files
committed
[Function add]
1.Add some functions of red black tree.
1 parent cd13103 commit 9e4ed76

File tree

2 files changed

+146
-0
lines changed

2 files changed

+146
-0
lines changed

Algorithm(4th_Edition)/algorithm_note.txt

+91
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,97 @@
10521052
if(cmplo <= 0 && cmphi >= 0) queue.enqueue(node.k);
10531053
if(cmphi > 0) keys(node.right, queue, lo, hi); //从当前结点开始向右遍历,直到接触到hi对应的结点,将所有之间的结点加入队列。[current-hi]
10541054
}
1055+
1056+
->性能分析:
1057+
1.树的高度决定了树中和有序性相关的操作。
1058+
2.在一个二叉查找树中,所有操作在最坏情况下所需的时间和树的高度成正比。
1059+
1060+
6. 2-3查找树:
1061+
2-结点:含有一个键和两条链接,类似于二叉树,左边链接的值小于键值,右边链接的键值大于键值。
1062+
2
1063+
/ \
1064+
1 3
1065+
1066+
3-结点:含有两个键和三条链接,左边链接的键值小于左键值,中间链接的键值在左键值和右键值之间,右链接的键值大于右键值。
1067+
4 7
1068+
/ | \
1069+
1 2 5 8 9
1070+
1071+
->查找结点get:
1072+
通过比较键值递归查找,如果找到则返回该节点,直到遍历为空,退出循环,返回空值,说明没有该结点。
1073+
->放置结点put:
1074+
添加新的结点之前需要通过get方法查找键,如果找到了,直接修改值,如果不为空,分为以下几种条件:
1075+
1.向2-结点中添加新键。
1076+
2.向一个父结点为2-结点的3-结点添加新键。
1077+
3.向一个父结点为3-结点的3-结点添加新键:需要一直遍历到根节点判断是不是2-结点,其中有一个是2-结点,则归纳到1的情况。
1078+
分解根节点:如果根结点为一个4-结点,继续将中间的键向上移添加一个新的结点。
1079+
1080+
7. 红黑二叉查找树:
1081+
1.红黑二叉查找树是一种2-3查找树的实现。
1082+
2.我们将树中的链接分为两种类型:
1083+
->红链接:将两个2-结点连接起来构成一个3-结点。
1084+
->黑链接:2-3树中的普通链接。
1085+
3.替换3-结点:
1086+
通过红链接将来通过二叉树来表示2-3链接。
1087+
将原来的3-结点转化成2-结点,并且将原来3-结点中的两个键通过红链接表示。
1088+
我们将这种方式表示的2-3树的二叉查找树成为红黑二叉查找树(红黑树)。
1089+
->红链接均为左链接。
1090+
->没有任何一个结点同时和两条红链接相连。
1091+
->该树是完美黑色平衡的,即任意空链接到根结点的路径上的黑链接数量相同。
1092+
实现:ca.mcmaster.chapter.three.rbtree.RedBlackBST<K, V>
1093+
public class RedBlackBST<K, V> {
1094+
private Node root;
1095+
public static final Boolean RED = true;
1096+
public static final Boolean BLACK = false;
1097+
private class Node{
1098+
K k;
1099+
V v;
1100+
Node left, right;
1101+
int N;
1102+
Boolean color;
1103+
public Node(K k, V v, int n, Boolean color) {
1104+
this.k = k;
1105+
this.v = v;
1106+
N = n;
1107+
this.color = color;
1108+
}
1109+
}
1110+
1111+
private Boolean isRed(Node node){
1112+
if(null == node) return false;
1113+
return node.color == RED;
1114+
}
1115+
1116+
public Node rotateLeft(Node node){ //将右侧的红链接与左链接(黑链接)交换
1117+
Node temp = node.right; //思考:如果将原父结点作为temp需要4条赋值语句,所以通过将右结点作为中间变量可以减少开销。
1118+
node.right = temp.left;
1119+
temp.left = node;
1120+
temp.color = node.color;
1121+
node.color = RED;
1122+
temp.N = node.N;
1123+
node.N = 1 + size(node.left) + size(node.right);
1124+
return temp;
1125+
}
1126+
public Node rotateRight(Node node){ //将左侧的红链接与右链接(黑链接)交换
1127+
Node temp = node.left;
1128+
node.left = temp.right;
1129+
temp.right = node;
1130+
temp.color = node.color;
1131+
temp.N = size(node);
1132+
node.N = 1 + size(node.left) + size(node.right);
1133+
return temp;
1134+
}
1135+
public int size() { return size(root); }
1136+
public int size(Node node){
1137+
if(null == node) return 0;
1138+
return node.N;
1139+
}
1140+
}
1141+
1142+
4.颜色转换:
1143+
->两个子链接都是红链接,那么我们可以将父结点向上的链接变成红链接,将两个子链接变成黑链接。
1144+
实现:ca.mcmaster.chapter.three.rbtree.RedBlackBST#filpColor(Node)
1145+
->根节点总是黑色的,根据上一条,我们总是会将根节点设置为红链接,但是我们要将父结点设置成黑链接,每次由红色变成黑色树的黑链接高度增加1.
10551146

10561147

10571148

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package ca.mcmaster.chapter.three.rbtree;
2+
3+
public class RedBlackBST<K, V> {
4+
private Node root;
5+
public static final Boolean RED = true;
6+
public static final Boolean BLACK = false;
7+
private class Node{
8+
K k;
9+
V v;
10+
Node left, right;
11+
int N;
12+
Boolean color;
13+
public Node(K k, V v, int n, Boolean color) {
14+
this.k = k;
15+
this.v = v;
16+
N = n;
17+
this.color = color;
18+
}
19+
}
20+
21+
private Boolean isRed(Node node){
22+
if(null == node) return false;
23+
return node.color == RED;
24+
}
25+
26+
public Node rotateLeft(Node node){
27+
Node temp = node.right;
28+
node.right = temp.left;
29+
temp.left = node;
30+
temp.color = node.color;
31+
node.color = RED;
32+
temp.N = node.N;
33+
node.N = 1 + size(node.left) + size(node.right);
34+
return temp;
35+
}
36+
public Node rotateRight(Node node){
37+
Node temp = node.left;
38+
node.left = temp.right;
39+
temp.right = node;
40+
temp.color = node.color;
41+
temp.N = size(node);
42+
node.N = 1 + size(node.left) + size(node.right);
43+
return temp;
44+
}
45+
public int size() { return size(root); }
46+
public int size(Node node){
47+
if(null == node) return 0;
48+
return node.N;
49+
}
50+
public void filpColor(Node node){
51+
node.color = RED;
52+
node.left.color = BLACK;
53+
node.right.color = BLACK;
54+
}
55+
}

0 commit comments

Comments
 (0)