紅黑樹
1、概念
紅黑樹(RBT)的定義:它或者是一顆空樹占调,或者是具有一下性質(zhì)的二叉查找樹暂题。
- 節(jié)點(diǎn)非紅即黑
- 根節(jié)點(diǎn)是黑色
- 所有NULL節(jié)點(diǎn)稱為葉子節(jié)點(diǎn),且認(rèn)為顏色為黑色
- 所有紅節(jié)點(diǎn)的子節(jié)點(diǎn)都為黑色
- 從任一節(jié)點(diǎn)到其葉子節(jié)點(diǎn)的所有路徑上都包含相同數(shù)目的黑節(jié)點(diǎn)
對平衡樹的改進(jìn):任意一個(gè)節(jié)點(diǎn)妈候,它的左右子樹的層次最多不超過一倍敢靡。
1.png
2挂滓、插入節(jié)點(diǎn)
1. 插入節(jié)點(diǎn):先按照二叉排序樹的方式插入一個(gè)節(jié)點(diǎn)(紅色)
2. 插入節(jié)點(diǎn)是根節(jié)點(diǎn): 解決:直接將節(jié)點(diǎn)涂黑
3. 插入節(jié)點(diǎn)的父節(jié)點(diǎn)是黑色: 不違背任何性質(zhì)苦银,不用調(diào)整
4. 插入節(jié)點(diǎn)的父節(jié)點(diǎn)是紅色,那么分以下幾種情況:
第一種情況:父節(jié)點(diǎn)是祖父節(jié)點(diǎn)的左孩子
情況1:祖父節(jié)點(diǎn)的另一個(gè)子節(jié)點(diǎn)(叔叔節(jié)點(diǎn))是紅色
對策: 將當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)和叔叔節(jié)點(diǎn)涂黑赶站,祖父節(jié)點(diǎn)涂紅幔虏,把當(dāng)前節(jié)點(diǎn)指向祖父節(jié)點(diǎn),從新的當(dāng)前節(jié)點(diǎn)開始算法
2.png
情況2:叔叔節(jié)點(diǎn)是黑色贝椿,右分兩種情況:
情況2.1:當(dāng)前節(jié)點(diǎn)是其父節(jié)點(diǎn)的右孩子
對策:當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)做為新的當(dāng)前節(jié)點(diǎn)想括,以新當(dāng)前節(jié)點(diǎn)為支點(diǎn)左旋。
3.png
情況2.2:當(dāng)前節(jié)點(diǎn)是其父節(jié)點(diǎn)的左孩子
對策:父節(jié)點(diǎn)變?yōu)楹谏硬娓腹?jié)點(diǎn)變紅色瑟蜈,再祖父節(jié)點(diǎn)為支點(diǎn)進(jìn)行右旋
4.png
第二種情況:父節(jié)點(diǎn)是祖父節(jié)點(diǎn)的右孩子(和上面情況一樣,將左全部變成右即可)
3渣窜、刪除節(jié)點(diǎn)
刪除節(jié)點(diǎn):先進(jìn)行二叉排序樹的刪除操作铺根,然后已替換節(jié)點(diǎn)作為當(dāng)前節(jié)點(diǎn)進(jìn)行后面的平衡操作
1. 當(dāng)前節(jié)點(diǎn)是紅色。對策:直接把當(dāng)前節(jié)點(diǎn)染成黑色乔宿,結(jié)束位迂。
2. 當(dāng)前節(jié)點(diǎn)x是黑色,分以下幾種情況:
第一種情況:被刪除節(jié)點(diǎn)是父節(jié)點(diǎn)的左孩子
2.1 當(dāng)前節(jié)點(diǎn)是根節(jié)點(diǎn)
對策:什么都不做
2.2 當(dāng)前節(jié)點(diǎn)x的兄弟節(jié)點(diǎn)是紅色(此時(shí)父節(jié)點(diǎn)和兄弟節(jié)點(diǎn)的子節(jié)點(diǎn)分為黑)
對策:把父節(jié)點(diǎn)染成紅色详瑞,兄弟節(jié)點(diǎn)染成黑色掂林,對父節(jié)點(diǎn)進(jìn)行左旋,重新設(shè)置x的兄弟節(jié)點(diǎn)
5.png
2.3 當(dāng)前節(jié)點(diǎn)x 的兄弟節(jié)點(diǎn)是黑色
2.3.1 兄弟節(jié)點(diǎn)的兩個(gè)孩子都是黑色
對策:將x的兄弟節(jié)點(diǎn)設(shè)為紅色坝橡,設(shè)置x的父節(jié)點(diǎn)為新的x節(jié)點(diǎn)
6.png
2.3.2 兄弟的右孩子是黑色泻帮,左孩子是紅色
對策:將x兄弟節(jié)點(diǎn)的左孩子設(shè)為黑色,將x兄弟節(jié)點(diǎn)設(shè)置紅色计寇,將x的兄弟節(jié)點(diǎn)右旋刑顺,右旋后氯窍,重新設(shè)置x的兄弟節(jié)點(diǎn)。
7.png
2.3.3 兄弟節(jié)點(diǎn)的右孩子是紅色
對策:把兄弟節(jié)點(diǎn)染成當(dāng)前節(jié)點(diǎn)父節(jié)點(diǎn)顏色蹲堂,把當(dāng)前節(jié)點(diǎn)父節(jié)點(diǎn)染成黑色狼讨,兄弟節(jié)點(diǎn)右孩子染成黑色,再以當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)為支點(diǎn)進(jìn)行左旋柒竞,算法結(jié)算
8.png
第二種情況:被刪除節(jié)點(diǎn)是父節(jié)點(diǎn)的右孩子(對策: 把第一種情況的左設(shè)置為右)
4政供、完整代碼(代碼有詳細(xì)的注釋)
import java.util.LinkedList;
/**
* 紅黑樹
* <p>
* author: bobo
* create time: 2018/12/18 3:39 PM
* email: jqbo84@163.com
*/
public class RBTree<E extends Comparable<E>> {
private static final boolean BLACK = true;
private static final boolean RED = false;
private Node<E> root;
private int size;
public Node<E> getRoot() {
return root;
}
public int getSize() {
return size;
}
/**
* 獲取顏色值
*
* @param p
*/
private boolean colorOf(Node<E> p) {
return (p == null ? BLACK : p.color);
}
/**
* 獲取父節(jié)點(diǎn)
*
* @param p
* @return
*/
private Node<E> parentOf(Node<E> p) {
return (p == null ? null : p.parent);
}
/**
* 設(shè)置節(jié)點(diǎn)的顏色
*
* @param p
* @param color
*/
private void setColor(Node<E> p, boolean color) {
if (p != null) {
p.color = color;
}
}
/**
* 獲取當(dāng)前節(jié)點(diǎn)的左節(jié)點(diǎn)
*
* @param p
* @return
*/
private Node<E> leftOf(Node<E> p) {
return (p == null ? null : p.leftChild);
}
/**
* 獲取當(dāng)前節(jié)點(diǎn)的右節(jié)點(diǎn)
*
* @param p
* @return
*/
private Node<E> rightOf(Node<E> p) {
return (p == null ? null : p.rightChild);
}
/**
* 左旋轉(zhuǎn)
*
* @param x
*/
public void leftRotate(Node<E> x) {
if (x == null) {
return;
}
//1.先取到x的右結(jié)點(diǎn)
Node<E> y = x.rightChild;
//2.把??接上x的右結(jié)點(diǎn)上
x.rightChild = y.leftChild;
if (y.leftChild != null) {
y.leftChild.parent = x;
}
//3.把y移到x的父結(jié)點(diǎn)上
y.parent = x.parent;
if (x.parent == null) {
root = y;
} else {
if (x.parent.leftChild == x) {
x.parent.leftChild = y;
} else {
x.parent.rightChild = y;
}
}
y.leftChild = x;
x.parent = y;
}
/**
* 右旋轉(zhuǎn)
*
* @param x
*/
public void rightRotate(Node<E> x) {
if (x == null) {
return;
}
//1.先取到x的左結(jié)點(diǎn)
Node<E> y = x.leftChild;
//2.把??接上x的左結(jié)點(diǎn)上
x.leftChild = y.rightChild;
if (y.rightChild != null) {
y.rightChild.parent = x;
}
//3.把y移到x的父結(jié)點(diǎn)上
y.parent = x.parent;
if (x.parent == null) {
root = y;
} else {
if (x.parent.leftChild == x) {
x.parent.leftChild = y;
} else {
x.parent.rightChild = y;
}
}
y.rightChild = x;
x.parent = y;
}
/**
* 插入節(jié)點(diǎn):先按照二叉排序樹的方式插入一個(gè)節(jié)點(diǎn),再查找最小不平衡子樹朽基,以最小不平衡子樹進(jìn)行下面的操作
*
* @param element
* @return
*/
public boolean insertElement(E element) {
if (element == null) {
return false;
}
Node<E> t = root;
if (t == null) {
root = new Node<>(element, null);
size = 1;
return true;
}
int cmp = 0;
Node<E> parent = null;
Comparable<E> e = element;
//1.查找可以插入的位置
do {
parent = t;
cmp = e.compareTo(t.element);
if (cmp < 0) {//比父結(jié)點(diǎn)小布隔,那么查左結(jié)點(diǎn)
t = t.leftChild;
} else if (cmp > 0) {//比父結(jié)點(diǎn)大,那么查右結(jié)點(diǎn)
t = t.rightChild;
} else {//相等稼虎,說明是同一個(gè)數(shù)據(jù)衅檀,不需要插入
return false;
}
} while (t != null);
//2.找到可以插入的位置,進(jìn)行插入
Node<E> child = new Node<>(element, parent);
if (cmp < 0) {
parent.leftChild = child;
} else {
parent.rightChild = child;
}
//平衡樹出現(xiàn)問題霎俩,需要修正
fixAfterInsertion(child);
size++;
return true;
}
/**
* 修正插入之后的平衡樹
*
* @param node
*/
public void fixAfterInsertion(Node<E> node) {
if (node == null) return;
node.color = RED;
while (node != null && node != root && node.parent.color == RED) {
//1.父節(jié)點(diǎn)是祖父節(jié)點(diǎn)的左孩子哀军,有3種情況
if (parentOf(node) == leftOf(parentOf(parentOf(node)))) {
//取叔叔節(jié)點(diǎn)
Node<E> uncleNode = rightOf(parentOf(parentOf(node)));
if (colorOf(uncleNode) == RED) {//情況1:祖父節(jié)點(diǎn)的另一個(gè)子節(jié)點(diǎn)(叔叔節(jié)點(diǎn))是紅色
//對策: 將當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)和叔叔節(jié)點(diǎn)涂黑,祖父節(jié)點(diǎn)涂紅打却,把當(dāng)前節(jié)點(diǎn)指向祖父節(jié)點(diǎn)杉适,從新的當(dāng)前節(jié)點(diǎn)開始算法
setColor(parentOf(node), BLACK);
setColor(uncleNode, BLACK);
setColor(parentOf(parentOf(node)), RED);
node = parentOf(parentOf(node));
} else {//情況2:叔叔節(jié)點(diǎn)是黑色
if (node == rightOf(parentOf(node))) {//情況2.1:當(dāng)前節(jié)點(diǎn)是其父節(jié)點(diǎn)的右孩子
//對策:當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)做為新的當(dāng)前節(jié)點(diǎn),以新當(dāng)前節(jié)點(diǎn)為支點(diǎn)左旋柳击。
node = parentOf(node);
leftRotate(node);
}
//情況2.2:當(dāng)前節(jié)點(diǎn)是其父節(jié)點(diǎn)的左孩子
//對策:父節(jié)點(diǎn)變?yōu)楹谏惩疲娓腹?jié)點(diǎn)變紅色,再祖父節(jié)點(diǎn)為支點(diǎn)進(jìn)行右旋
setColor(parentOf(node), BLACK);
setColor(parentOf(parentOf(node)), RED);
rightRotate(parentOf(parentOf(node)));
}
}
//2.父節(jié)點(diǎn)是祖父節(jié)點(diǎn)的右孩子
else {
//取叔叔節(jié)點(diǎn)
Node<E> uncleNode = leftOf(parentOf(parentOf(node)));
if (colorOf(uncleNode) == RED) {//情況1:祖父節(jié)點(diǎn)的另一個(gè)子節(jié)點(diǎn)(叔叔節(jié)點(diǎn))是紅色
//對策: 將當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)和叔叔節(jié)點(diǎn)涂黑捌肴,祖父節(jié)點(diǎn)涂紅蹬叭,把當(dāng)前節(jié)點(diǎn)指向祖父節(jié)點(diǎn),從新的當(dāng)前節(jié)點(diǎn)開始算法
setColor(parentOf(node), BLACK);
setColor(uncleNode, BLACK);
setColor(parentOf(parentOf(node)), RED);
node = parentOf(parentOf(node));
} else {//情況2:叔叔節(jié)點(diǎn)是黑色
if (node == leftOf(parentOf(node))) {//情況2.1:當(dāng)前節(jié)點(diǎn)是其父節(jié)點(diǎn)的左孩子
//對策:當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)做為新的當(dāng)前節(jié)點(diǎn)状知,以新當(dāng)前節(jié)點(diǎn)為支點(diǎn)右旋秽五。
node = parentOf(node);
rightRotate(node);
}
//情況2.2:當(dāng)前節(jié)點(diǎn)是其父節(jié)點(diǎn)的右孩子
//對策:父節(jié)點(diǎn)變?yōu)楹谏娓腹?jié)點(diǎn)變紅色试幽,再祖父節(jié)點(diǎn)為支點(diǎn)進(jìn)行左旋
setColor(parentOf(node), BLACK);
setColor(parentOf(parentOf(node)), RED);
leftRotate(parentOf(parentOf(node)));
}
}
}
root.color = BLACK;
}
/**
* 根據(jù)當(dāng)前的值筝蚕,獲取當(dāng)前節(jié)點(diǎn)
*
* @param element
* @return
*/
public Node<E> getNode(E element) {
if (element == null) {
return null;
}
Node<E> t = root;
Comparable<E> e = element;
while (t != null) {
int cmp = e.compareTo(t.element);
if (cmp < 0) {
t = t.leftChild;
} else if (cmp > 0) {
t = t.rightChild;
} else {
return t;
}
}
return null;
}
/**
* 獲取傳入P節(jié)點(diǎn)下面最小的節(jié)點(diǎn)
*
* @param p
* @return
*/
public Node<E> getMinLeftNode(Node<E> p) {
if (p == null) {
return null;
}
Node<E> t = p;
while (t.leftChild != null) {
t = t.leftChild;
}
return t;
}
/**
* 刪除元素
*
* @param element
*/
public void remove(E element) {
//查找當(dāng)前的節(jié)點(diǎn)
Node<E> node = getNode(element);
if (node == null) {
return;
}
deleteElement(node);
}
/**
* 刪除當(dāng)前的節(jié)點(diǎn)
*
* @param node
*/
public void deleteElement(Node<E> node) {
if (node.leftChild != null && node.rightChild != null) {
Node<E> s = getMinLeftNode(node.rightChild);
node.element = s.element;
node = s;
}
Node<E> t = (node.leftChild != null ? node.leftChild : node.rightChild);
if (t == null) {
Node<E> parent = node.parent;
if (parent == null) {
root = null;
} else {
// 注重:如果刪除節(jié)點(diǎn)是黑色,那么一定要先修正紅黑二叉樹铺坞,在做下面的刪除動作
if (node.color == BLACK) {
fixAfterDeletion(node);
}
if (parent.leftChild == node) {
parent.leftChild = null;
} else {
parent.rightChild = null;
}
node.parent = null;
}
} else {
t.parent = node.parent;
if (node.parent == null) {
root = t;
} else {
if (node.parent.leftChild == node) {
node.parent.leftChild = t;
} else {
node.parent.rightChild = t;
}
}
node.leftChild = node.rightChild = node.parent = null;
if (node.color == BLACK) {
fixAfterDeletion(t);
}
}
size--;
}
/**
* 刪除節(jié)點(diǎn)后起宽,修正紅黑樹
* @param node
*/
public void fixAfterDeletion(Node<E> node) {
while (node != root && colorOf(node) == BLACK) {
if (leftOf(parentOf(node)) == node) { //被刪除節(jié)點(diǎn)是父節(jié)點(diǎn)的左孩子
//拿到node的兄弟節(jié)點(diǎn)
Node<E> sib = rightOf(parentOf(node));
if (colorOf(sib) == RED) { //2.2 當(dāng)前節(jié)點(diǎn)x的兄弟節(jié)點(diǎn)是紅色(此時(shí)父節(jié)點(diǎn)和兄弟節(jié)點(diǎn)的子節(jié)點(diǎn)分為黑)
//對策:把父節(jié)點(diǎn)染成紅色,兄弟節(jié)點(diǎn)染成黑色济榨,對父節(jié)點(diǎn)進(jìn)行左旋坯沪,重新設(shè)置x的兄弟節(jié)點(diǎn)
setColor(parentOf(node), RED);
setColor(sib, BLACK);
leftRotate(parentOf(node));
sib = rightOf(parentOf(node));
}
if (colorOf(sib) == BLACK) {//2.3 當(dāng)前節(jié)點(diǎn)x 的兄弟節(jié)點(diǎn)是黑色
if (colorOf(leftOf(sib)) == BLACK && colorOf(rightOf(sib)) == BLACK) {//2.3.1 兄弟節(jié)點(diǎn)的兩個(gè)孩子都是黑色
//對策:將x的兄弟節(jié)點(diǎn)設(shè)為紅色,設(shè)置x的父節(jié)點(diǎn)為新的x節(jié)點(diǎn)
setColor(sib, RED);
node = parentOf(node);
} else {
if (colorOf(rightOf(sib)) == BLACK) {//2.3.2 兄弟的右孩子是黑色擒滑,左孩子是紅色
//對策:將x兄弟節(jié)點(diǎn)的左孩子設(shè)為黑色腐晾,將x兄弟節(jié)點(diǎn)設(shè)置紅色叉弦,將x的兄弟節(jié)點(diǎn)右旋,右旋后藻糖,重新設(shè)置x的兄弟節(jié)點(diǎn)淹冰。
setColor(leftOf(sib), BLACK);
setColor(sib, RED);
rightRotate(sib);
sib = rightOf(parentOf(node));
}
//2.3.3 兄弟節(jié)點(diǎn)的右孩子是紅色
//對策:把兄弟節(jié)點(diǎn)染成當(dāng)前節(jié)點(diǎn)父節(jié)點(diǎn)顏色,把當(dāng)前節(jié)點(diǎn)父節(jié)點(diǎn)染成黑色巨柒,兄弟節(jié)點(diǎn)右孩子染成黑色樱拴,再以當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)為支點(diǎn)進(jìn)行左旋,算法結(jié)算
setColor(sib, colorOf(parentOf(node)));
setColor(parentOf(node), BLACK);
setColor(rightOf(sib), BLACK);
leftRotate(parentOf(node));
node = root;
}
}
} else { //被刪除節(jié)點(diǎn)是父節(jié)點(diǎn)的右孩子, 對策: 把上面的左設(shè)置為右
//拿到node的兄弟節(jié)點(diǎn)
Node<E> sib = leftOf(parentOf(node));
if (colorOf(sib) == RED) { //2.2 當(dāng)前節(jié)點(diǎn)x的兄弟節(jié)點(diǎn)是紅色(此時(shí)父節(jié)點(diǎn)和兄弟節(jié)點(diǎn)的子節(jié)點(diǎn)分為黑)
//對策:把父節(jié)點(diǎn)染成紅色洋满,兄弟節(jié)點(diǎn)染成黑色晶乔,對父節(jié)點(diǎn)進(jìn)行右旋,重新設(shè)置x的兄弟節(jié)點(diǎn)
setColor(parentOf(node), RED);
setColor(sib, BLACK);
rightRotate(parentOf(node));
sib = leftOf(parentOf(node));
}
if (colorOf(sib) == BLACK) {//2.3 當(dāng)前節(jié)點(diǎn)x 的兄弟節(jié)點(diǎn)是黑色
if (colorOf(leftOf(sib)) == BLACK && colorOf(rightOf(sib)) == BLACK) {//2.3.1 兄弟節(jié)點(diǎn)的兩個(gè)孩子都是黑色
//對策:將x的兄弟節(jié)點(diǎn)設(shè)為紅色牺勾,設(shè)置x的父節(jié)點(diǎn)為新的x節(jié)點(diǎn)
setColor(sib, RED);
node = parentOf(node);
} else {
if (colorOf(leftOf(sib)) == BLACK) {//2.3.2 兄弟的左孩子是黑色正罢,右孩子是紅色
//對策:將x兄弟節(jié)點(diǎn)的右孩子設(shè)為黑色,將x兄弟節(jié)點(diǎn)設(shè)置紅色驻民,將x的兄弟節(jié)點(diǎn)左旋翻具,左旋后,重新設(shè)置x的兄弟節(jié)點(diǎn)川无。
setColor(rightOf(sib), BLACK);
setColor(sib, RED);
leftRotate(sib);
sib = leftOf(parentOf(node));
}
//2.3.3 兄弟節(jié)點(diǎn)的左孩子是紅色
//對策:把兄弟節(jié)點(diǎn)染成當(dāng)前節(jié)點(diǎn)父節(jié)點(diǎn)顏色呛占,把當(dāng)前節(jié)點(diǎn)父節(jié)點(diǎn)染成黑色虑乖,兄弟節(jié)點(diǎn)左孩子染成黑色懦趋,再以當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)為支點(diǎn)進(jìn)行右旋,算法結(jié)算
setColor(sib, colorOf(parentOf(node)));
setColor(parentOf(node), BLACK);
setColor(leftOf(sib), BLACK);
rightRotate(parentOf(node));
node = root;
}
}
}
}
}
/**
* 一層一層打印出數(shù)據(jù)
*
* @param root)
*/
public void showRBTree(Node<E> root) {
if (root == null) {
return;
}
LinkedList<Node<E>> list = new LinkedList<>();
list.offer(root);
while (!list.isEmpty()) {
Node<E> node = list.pop();
System.out.println("node.element = " + node.element + ", color = " + node.color);
if (node.leftChild != null) {
list.offer(node.leftChild);
}
if (node.rightChild != null) {
list.offer(node.rightChild);
}
}
}
/**
* 紅黑樹結(jié)點(diǎn)
*
* @param <E>
*/
public class Node<E extends Comparable>{
E element;
Node<E> leftChild;
Node<E> rightChild;
Node<E> parent;
//0:黑色 1:紅色
boolean color = BLACK;
public Node(E element, Node<E> parent) {
this.element = element;
this.parent = parent;
}
}
}
5疹味、測試
@Test
public void testRBTree(){
Integer[] nums = {13,8,5,11,6,22,27,25,14,17};
RBTree<Integer> tree = new RBTree<>();
for (int i = 0; i < nums.length; i++) {
Integer num = nums[i];
tree.insertElement(num);
}
tree.showRBTree(tree.getRoot());
tree.remove(25);
System.out.println("---------------------------------------- ");
tree.showRBTree(tree.getRoot());
System.out.println("---------------------------------------- ");
for (Integer num : nums) {
tree.remove(num);
tree.showRBTree(tree.getRoot());
System.out.println("------------------------------------ : " + num);
}
}
測試結(jié)果: true:是黑色仅叫,false:是紅色
---------------打印插入數(shù)據(jù)---------------
node.element = 13, color = true
node.element = 8, color = false
node.element = 25, color = false
node.element = 5, color = true
node.element = 11, color = true
node.element = 17, color = true
node.element = 27, color = true
node.element = 6, color = false
node.element = 14, color = false
node.element = 22, color = false
---------------------------------------- 刪除: 25
node.element = 13, color = true
node.element = 8, color = false
node.element = 17, color = false
node.element = 5, color = true
node.element = 11, color = true
node.element = 14, color = true
node.element = 27, color = true
node.element = 6, color = false
node.element = 22, color = false
----------------循環(huán)刪除-----------------
------------------------------------ 刪除: 13
node.element = 14, color = true
node.element = 8, color = false
node.element = 22, color = false
node.element = 5, color = true
node.element = 11, color = true
node.element = 17, color = true
node.element = 27, color = true
node.element = 6, color = false
------------------------------------ 刪除: 8
node.element = 14, color = true
node.element = 6, color = false
node.element = 22, color = false
node.element = 5, color = true
node.element = 11, color = true
node.element = 17, color = true
node.element = 27, color = true
------------------------------------ 刪除: 5
node.element = 14, color = true
node.element = 6, color = false
node.element = 22, color = false
node.element = 11, color = false
node.element = 17, color = true
node.element = 27, color = true
------------------------------------ 刪除: 11
node.element = 14, color = true
node.element = 6, color = false
node.element = 22, color = false
node.element = 17, color = true
node.element = 27, color = true
------------------------------------ 刪除: 6
node.element = 14, color = true
node.element = 22, color = false
node.element = 17, color = true
node.element = 27, color = true
------------------------------------ 刪除: 22
node.element = 14, color = true
node.element = 27, color = false
node.element = 17, color = false
------------------------------------ 刪除: 27
node.element = 14, color = true
node.element = 17, color = false
------------------------------------ 刪除: 25
node.element = 14, color = true
node.element = 17, color = false
------------------------------------ 刪除: 14
node.element = 17, color = false
------------------------------------ 刪除: 17
附上插入數(shù)據(jù)的紅黑樹 筆記 如圖:
9.jpg