AVL樹
一、概念
AVL樹,也稱平衡二叉搜索樹,AVL樹是一棵二叉搜索樹,并且能通過一定的平衡處理機(jī)制保證二叉搜索樹的平衡,使得查詢效率更高。
特點(diǎn):
- AVL樹是一棵二叉搜索樹。
- AVL樹的左右子結(jié)點(diǎn)也是AVL樹。
- 每個結(jié)點(diǎn)的左右子結(jié)點(diǎn)的高度之差的絕對值最多為1,即平衡因子的范圍為[-1,1]。
平衡處理機(jī)制:
采用旋轉(zhuǎn)進(jìn)行平衡處理,一共有四種形式的旋轉(zhuǎn):右單旋、左單旋、左右雙旋和右左雙旋。

AVL樹
二、數(shù)據(jù)結(jié)構(gòu)
struct AVLTreeNode {
int value;
int height;
AVLTreeNode *left;
AVLTreeNode *right;
};
三、相關(guān)操作
- 插入
- 刪除
- 查找
四、實(shí)現(xiàn)
#include<stdio.h>
#include<malloc.h>
struct AVLTreeNode {
int value;
int height;
AVLTreeNode *left;
AVLTreeNode *right;
};
AVLTreeNode* makeEmpty(AVLTreeNode* T) {
if (T != NULL) {
makeEmpty(T->left);
makeEmpty(T->right);
free(T);
}
return NULL;
}
int height(AVLTreeNode* P) { //計算AVL結(jié)點(diǎn)高度
if (P == NULL) {
return -1;
} else {
return P->height;
}
}
int max(int a, int b) { //獲取最大值
return a > b ? a : b;
}
int absMinus(int a, int b) { //獲取相減后的絕對值
int result;
if(a >= b) {
result = a - b;
} else {
result = b - a;
}
return result;
}
/* 左邊的結(jié)點(diǎn)單旋(即向右旋轉(zhuǎn)) */
AVLTreeNode* singleRotateWithLeft(AVLTreeNode* K2) {
AVLTreeNode* K1;
K1 = K2->left;
K2->left = K1->right;
K1->right = K2;
K2->height = max(height(K2->left), height(K2->right)) + 1;
K1->height = max(height(K1->left), K2->height) + 1;
return K1;
}
/* 右邊的結(jié)點(diǎn)單旋(即向左旋轉(zhuǎn)) */
AVLTreeNode* singleRotateWithRight(AVLTreeNode* K2) {
AVLTreeNode* K1;
K1 = K2->right;
K2->right = K1->left;
K1->left = K2;
K2->height = max(height(K2->left), height(K2->right)) + 1;
K1->height = max(K2->height, height(K1->right)) + 1;
return K1;
}
/* 左邊的結(jié)點(diǎn)雙旋(即先向左旋轉(zhuǎn)再向右旋轉(zhuǎn)) */
AVLTreeNode* doubleRotateWithLeft(AVLTreeNode* K3) {
K3->left = singleRotateWithRight(K3->left);
return singleRotateWithLeft(K3);
}
/* 右邊的結(jié)點(diǎn)雙旋(即先向右旋轉(zhuǎn)再向左旋轉(zhuǎn)) */
AVLTreeNode* doubleRotateWithRight(AVLTreeNode* K3) {
K3->right = singleRotateWithLeft(K3->right);
return singleRotateWithRight(K3);
}
AVLTreeNode* insertALV(int X, AVLTreeNode* T) { //遞歸插入,返回根結(jié)點(diǎn)
if (T == NULL) {
T = (AVLTreeNode*)malloc(sizeof(AVLTreeNode));
if (T == NULL) {
printf("out of memory\n");
} else {
T->value = X;
T->height = 0;
T->left = T->right = NULL;
}
} else if (X < T->value) { /* 左子樹插入新結(jié)點(diǎn) */
T->left = insertALV(X, T->left); //遞歸插入左子樹,返回根結(jié)點(diǎn)
if (absMinus(height(T->left), height(T->right)) == 2)
if (X < T->left->value)
T = singleRotateWithLeft(T);
else
T = doubleRotateWithLeft(T);
} else if (X > T->value) { /* 右子樹插入新結(jié)點(diǎn) */
T->right = insertALV(X, T->right); //遞歸插入右子樹,返回根結(jié)點(diǎn)
if (absMinus(height(T->left), height(T->right)) == 2)
if (X > T->right->value)
T = singleRotateWithRight(T);
else
T = doubleRotateWithRight(T);
} else {
printf("already exist\n");
}
T->height = max(height(T->left), height(T->right)) + 1; //更新根結(jié)點(diǎn)高度,左右子節(jié)點(diǎn)高度的最大值加1
return T; //返回根結(jié)點(diǎn)
}
AVLTreeNode* deleteAVL(int X, AVLTreeNode* T) { //遞歸刪除,返回根結(jié)點(diǎn)
if(T == NULL) {
printf("find null\n");
} else if (X < T->value) {
T->left = deleteAVL(X, T->left); //遞歸刪除左子樹,返回根結(jié)點(diǎn)(當(dāng)前結(jié)點(diǎn)的右子樹結(jié)點(diǎn)高度比較大)
if(absMinus(height(T->left), height(T->right)) == 2) {
AVLTreeNode *p = T->right;
if(height(p->left) > height(p->right)) { //當(dāng)前結(jié)點(diǎn)的右子樹結(jié)點(diǎn)的左子樹結(jié)點(diǎn)高度比較大,對右邊的結(jié)點(diǎn)雙旋
T = doubleRotateWithRight(T);
} else { //當(dāng)前結(jié)點(diǎn)的右子樹結(jié)點(diǎn)的右子樹結(jié)點(diǎn)高度比較大,對右邊的結(jié)點(diǎn)單旋
T = singleRotateWithRight(T);
}
}
} else if (X > T->value) { //遞歸刪除右子樹,返回根結(jié)點(diǎn)(當(dāng)前結(jié)點(diǎn)的左子樹結(jié)點(diǎn)高度比較大)
T->right = deleteAVL(X, T->right);
if(absMinus(height(T->left), height(T->right)) == 2) {
AVLTreeNode *p = T->left;
if(height(p->left) < height(p->right)) { //當(dāng)前結(jié)點(diǎn)的左子樹結(jié)點(diǎn)的右子樹結(jié)點(diǎn)高度比較大,對左邊的結(jié)點(diǎn)雙旋
T = doubleRotateWithLeft(T);
} else { //當(dāng)前結(jié)點(diǎn)的左子樹結(jié)點(diǎn)的左子樹結(jié)點(diǎn)高度比較大,對左邊的結(jié)點(diǎn)單旋
T = singleRotateWithLeft(T);
}
}
} else {
if(T->left != NULL && T->right != NULL) { //待刪除的結(jié)點(diǎn)有兩個孩子結(jié)點(diǎn)
if(height(T->left) > height(T->right)) { //當(dāng)前結(jié)點(diǎn)的左子樹結(jié)點(diǎn)高度比較大
AVLTreeNode *p = T->left;
while(p->right != NULL) { //尋找當(dāng)前結(jié)點(diǎn)的前驅(qū)結(jié)點(diǎn),用于刪除
p = p->right;
}
T->value = p->value;
T->left = deleteAVL(p->value, T->left);
} else { //當(dāng)前結(jié)點(diǎn)的右子樹結(jié)點(diǎn)高度比較大
AVLTreeNode *p = T->right;
while(p->left != NULL) { //尋找當(dāng)前結(jié)點(diǎn)的后繼結(jié)點(diǎn),用于刪除
p = p->left;
}
T->value = p->value;
T->right = deleteAVL(p->value, T->right);
}
} else if(T->left == NULL && T->right == NULL){ //待刪除的結(jié)點(diǎn)無孩子結(jié)點(diǎn)
T = NULL;
} else if(T->right == NULL) { //待刪除的結(jié)點(diǎn)只有左孩子結(jié)點(diǎn)
AVLTreeNode *p = T;
T = T->left;
free(p);
} else { //待刪除的結(jié)點(diǎn)只有右孩子結(jié)點(diǎn)
AVLTreeNode *p = T;
T = T->right;
free(p);
}
}
if(T != NULL) {
T->height = max(height(T->left), height(T->right)) + 1; //更新根結(jié)點(diǎn)高度,左右子節(jié)點(diǎn)高度的最大值加1
}
return T;
}
/* 查找X元素所在的位置 */
AVLTreeNode* findAVL(int X, AVLTreeNode* T) {
if (T == NULL) {
return NULL;
} else if (X < T->value) {
return findAVL(X, T->left);
} else if (X > T->value) {
return findAVL(X, T->right);
} else {
return T;
}
}
/* 前序遍歷二叉樹 */
void preorderTravel(AVLTreeNode* T) {
if (T != NULL) {
printf("%d ", T->value);
preorderTravel(T->left);
preorderTravel(T->right);
}
}
/* 中序遍歷二叉樹 */
void inorderTravel(AVLTreeNode* T) {
if (T != NULL) {
inorderTravel(T->left);
printf("%d ", T->value);
inorderTravel(T->right);
}
}
/* 后序遍歷二叉樹 */
void postorderTravel(AVLTreeNode* T) {
if (T != NULL) {
postorderTravel(T->left);
postorderTravel(T->right);
printf("%d ", T->value);
}
}
AVLTreeNode* findMin(AVLTreeNode* T) { //查找最小值
if (T == NULL) {
return NULL;
} else if (T->left == NULL) {
return T;
} else {
return findMin(T->left);
}
}
AVLTreeNode* findMax(AVLTreeNode* T) { //查找最大值
if (T == NULL) {
return NULL;
} else if (T->right == NULL) {
return T;
} else {
return findMax(T->right);
}
}
/* 先序遍歷打印二叉樹信息 */
void printTree(AVLTreeNode* T, int value, int direction) {
if (T != NULL) {
if (direction == 0) {
printf("%2d is root\n", T->value);
} else {
printf("%2d is %2d's %6s child\n", T->value, value, direction == 1 ? "right" : "left");
}
printTree(T->left, T->value, -1);
printTree(T->right, T->value, 1);
}
}
void main() {
AVLTreeNode* T;
T = makeEmpty(NULL);
T = insertALV(5, T);
T = insertALV(4, T);
T = insertALV(7, T);
T = insertALV(2, T);
T = insertALV(6, T);
T = insertALV(3, T);
T = insertALV(8, T);
T = insertALV(1, T);
T = insertALV(9, T);
T = insertALV(11, T);
T = insertALV(10, T);
printf("Root: %d\n", T->value);
printf("樹的詳細(xì)信息: \n");
printTree(T, T->value, 0);
printf("前序遍歷二叉樹: ");
preorderTravel(T);
printf("\n");
printf("中序遍歷二叉樹: ");
inorderTravel(T);
printf("\n");
printf("后序遍歷二叉樹: ");
postorderTravel(T);
printf("\n");
printf("最大值: %d\n", findMax(T)->value);
printf("最小值: %d\n", findMin(T)->value);
AVLTreeNode *node = findAVL(11, T);
if(node == NULL) {
printf("find null\n");
} else {
printf("find %d\n", node->value);
}
T = deleteAVL(10, T);
T = deleteAVL(1, T);
T = deleteAVL(2, T);
T = deleteAVL(4, T);
printf("樹的詳細(xì)信息: \n");
printTree(T, T->value, 0);
}
紅黑樹
一、概念
紅黑樹(Red Black Tree)是一種自平衡二叉搜索樹。
特點(diǎn):
- 紅黑樹是一棵二叉搜索樹。
- 每個結(jié)點(diǎn)是紅色或黑色。
- 根結(jié)點(diǎn)是黑色。
- 葉子結(jié)點(diǎn)(NIL節(jié)點(diǎn))是黑色。
- 紅色結(jié)點(diǎn)的兩個子結(jié)點(diǎn)都是黑色(如果子結(jié)點(diǎn)是紅色,那么父結(jié)點(diǎn)一定是黑色)。
- 從任意結(jié)點(diǎn)到其每個葉子結(jié)點(diǎn)的路徑包含相同數(shù)目的黑色結(jié)點(diǎn)。
平衡處理機(jī)制:
通過變色及旋轉(zhuǎn)保持黑結(jié)點(diǎn)平衡。

紅黑樹
二、數(shù)據(jù)結(jié)構(gòu)
struct RBTreeNode {
int value; //value
bool isRed; //結(jié)點(diǎn)顏色
RBTreeNode *parent; //父結(jié)點(diǎn)
RBTreeNode *left; //左子樹
RBTreeNode *right; //右子樹
};
三、相關(guān)操作
- 插入
- 查找
- 刪除
紅黑樹相關(guān)操作-1
紅黑樹相關(guān)操作-2
四、實(shí)現(xiàn)
#include <stdio.h>
#include <malloc.h>
struct RBTreeNode {
int value; //value
bool isRed; //結(jié)點(diǎn)顏色
RBTreeNode *parent; //父結(jié)點(diǎn)
RBTreeNode *left; //左子樹
RBTreeNode *right; //右子樹
};
/*定義葉子結(jié)點(diǎn)*/
RBTreeNode *nil;
/*獲取祖父結(jié)點(diǎn)*/
RBTreeNode* getAncestor(RBTreeNode* node) {
if (node->parent == nil) {
return NULL;
} else {
return node->parent->parent;
}
}
/*獲取叔父結(jié)點(diǎn)*/
RBTreeNode* getUncle(RBTreeNode* node) {
RBTreeNode* ancestor = getAncestor(node);
if(ancestor == NULL || ancestor == nil) {
return NULL;
} else if (ancestor->left == node->parent) {
return ancestor->right;
} else {
return ancestor->left;
}
}
/*左旋*/
RBTreeNode* rotateLeft(RBTreeNode* root, RBTreeNode* node) {
if(node->right != nil) {
//當(dāng)前結(jié)點(diǎn)的右結(jié)點(diǎn)
RBTreeNode* right = node->right;
node->right = right->left;
if (right->left != nil) {
right->left->parent = node;
}
right->parent = node->parent;
if (node->parent == nil) {
//node本來為根結(jié)點(diǎn),此時變化為原來node的右結(jié)點(diǎn)
root = right;
} else {
if (node == node->parent->left) {
node->parent->left = right;
} else {
node->parent->right = right;
}
}
right->left = node;
node->parent = right;
}
return root;
}
/*右旋*/
RBTreeNode* rotateRight(RBTreeNode* root, RBTreeNode* node) {
if (node->left != nil) {
//當(dāng)前結(jié)點(diǎn)的左結(jié)點(diǎn)
RBTreeNode* left = node->left;
node->left = left->right;
if (left->right != nil) {
left->right->parent = node;
}
left->parent = node->parent;
if (node->parent == nil) {
//node本來為根結(jié)點(diǎn),此時變化為原來node的左結(jié)點(diǎn)
root = left;
} else {
if (node == node->parent->left) {
node->parent->left = left;
} else {
node->parent->right = left;
}
}
left->right = node;
node->parent = left;
}
return root;
}
/*插入修復(fù)*/
RBTreeNode* fixInsert(RBTreeNode* root, RBTreeNode* node) {
RBTreeNode* uncle;
while(node->parent->isRed == true) {
RBTreeNode* ancestor = getAncestor(node);
if(node->parent == ancestor->left) {
uncle = ancestor->right; //獲取叔父結(jié)點(diǎn)
if (uncle->isRed == true) { //case 1 如果叔父結(jié)點(diǎn)為紅色(此時祖父結(jié)點(diǎn)一定為黑),則把父結(jié)點(diǎn)和叔父結(jié)點(diǎn)著黑,祖父結(jié)點(diǎn)著紅,node上移到祖父結(jié)點(diǎn)
uncle->isRed = false;
node->parent->isRed = false;
ancestor->isRed = true;
node = ancestor;
} else {
if (node == node->parent->right) { //case 3 如果叔父結(jié)點(diǎn)為黑色, node為右結(jié)點(diǎn), 循環(huán)變量node變?yōu)閚ode的父親結(jié)點(diǎn),左旋轉(zhuǎn)變化后的node結(jié)點(diǎn), 變?yōu)閏ase2的情況
node = node->parent;
root = rotateLeft(root, node);
}
//case 2 叔父結(jié)點(diǎn)為黑色,且node為左結(jié)點(diǎn),node的父結(jié)點(diǎn)著黑,node的祖父著紅,然后旋轉(zhuǎn)node的祖父結(jié)點(diǎn)
node->parent->isRed = false;
ancestor->isRed = true;
root = rotateRight(root, ancestor);
}
} else { //對稱 修復(fù)同上
uncle = ancestor->left;
if (uncle->isRed == true) {
uncle->isRed = false;
node->parent->isRed = false;
ancestor->isRed = true;
node = ancestor;
} else {
if (node == node->parent->left) {
node = node->parent;
root = rotateRight(root, node);
}
node->parent->isRed = false;
ancestor->isRed = true;
root = rotateLeft(root, ancestor);
}
}
}
//case 1中可能會把node變?yōu)閞oot,并將node設(shè)置成紅色,故需要此步確保正確
root->isRed = false;
return root;
}
/*通過value插入一個結(jié)點(diǎn)*/
RBTreeNode* addNodeByValue(RBTreeNode* root, int value) {
if (root == NULL) {
root = (RBTreeNode*)malloc(sizeof(RBTreeNode));
//初始化nil結(jié)點(diǎn)
nil = (RBTreeNode*)malloc(sizeof(RBTreeNode));
nil->isRed = false;
//設(shè)置結(jié)點(diǎn)的指向
root->parent = nil;
root->left = nil;
root->right = nil;
//設(shè)置結(jié)點(diǎn)屬性,value 和color
root->value = value;
root->isRed = false;
} else {
RBTreeNode* node = root;
/*插入結(jié)點(diǎn)的父結(jié)點(diǎn)*/
RBTreeNode* p = nil;
while (node != nil) {
p = node;
if(value > node->value) {
node = node->right;
} else if (value < node->value) {
node = node->left;
} else {
return root;
}
}
node = (RBTreeNode*)malloc(sizeof(RBTreeNode));
node->parent = p;
node->left = nil;
node->right = nil;
node->value = value;
node->isRed = true;
if (value < p->value) {
p->left = node;
} else {
p->right = node;
}
root = fixInsert(root, node);
}
return root;
}
/*查找實(shí)際要刪除的結(jié)點(diǎn)*/
RBTreeNode* getRealRemoveNode(RBTreeNode* root, RBTreeNode* node) {
//查找右結(jié)點(diǎn)的最小結(jié)點(diǎn)
RBTreeNode* p = node->right;
while (p->left != nil) {
p = p->left;
}
return p;
}
/*查找某個結(jié)點(diǎn)*/
RBTreeNode* findNodeByValue(RBTreeNode* node, int value) {
if (node == nil) {
return NULL;
}
if (node->value < value) {
return findNodeByValue(node->right, value);
} else if (node->value > value) {
return findNodeByValue(node->left, value);
} else {
return node;
}
}
/*刪除修復(fù)*/
RBTreeNode* fixRemove(RBTreeNode* root, RBTreeNode* node) {
while (node != root && node->isRed == false) { //循環(huán)結(jié)束條件為:node為根結(jié)點(diǎn)或者node結(jié)點(diǎn)為紅色
if (node == node->parent->left) {
RBTreeNode* brother = node->parent->right; //brother為node的兄弟結(jié)點(diǎn)
if (brother->isRed == true) { //case 1 兄弟結(jié)點(diǎn)為紅色(先讓兄弟結(jié)點(diǎn)變黑色)
brother->isRed = false;
node->parent->isRed = true;
root = rotateLeft(root, node->parent);
brother = node->parent->right; //brother一定為黑色,因?yàn)閚ode->parent為紅色
}
//brother一定為黑色
if (brother == nil) { //兄弟結(jié)點(diǎn)為葉子結(jié)點(diǎn),說明當(dāng)前結(jié)點(diǎn)也為葉子結(jié)點(diǎn),循環(huán)結(jié)束。
break;
} else if (brother->left->isRed == false && brother->right->isRed == false) { //case2 兄弟結(jié)點(diǎn)的兩個子結(jié)點(diǎn)都為黑
brother->isRed = true;
node = node->parent;
} else if (brother->left->isRed == true) { //case3 兄弟結(jié)點(diǎn)的左子樹為紅色,右子樹為黑色
brother->isRed = true;
brother->left->isRed = false;
root = rotateRight(root, brother);
brother = node->parent->right;
} else {
//case 4 兄弟結(jié)點(diǎn)的右子樹為紅色
brother->isRed = node->parent->isRed;
node->parent->isRed = false;
brother->right->isRed = false;
root = rotateLeft(root, node->parent);
node = root; //循環(huán)的出口
}
} else { //對稱 修復(fù)同上
RBTreeNode* brother = node->parent->left;
if (brother->isRed == true) { //case 1
brother->isRed = false;
node->parent->isRed = true;
root = rotateRight(root, node->parent);
brother = node->parent->left;
}
if (brother == nil) {
break;
} else if (brother->left->isRed == false && brother->right->isRed == false) { //case 2
brother->isRed = true;
node = node->parent;
} else if (brother->right->isRed == true) { //case 3
brother->isRed = true;
brother->right->isRed = false;
root = rotateLeft(root, brother);
brother = node->parent->left;
} else { //case 4
brother->isRed = node->parent->isRed;
node->parent->isRed = false;
brother->left->isRed = false;
root = rotateRight(root, node->parent);
node = root; //循環(huán)的出口
}
}
}
//case 2中,當(dāng)前結(jié)點(diǎn)的兄弟結(jié)點(diǎn)的兩個子結(jié)點(diǎn)都為黑色,將兄弟結(jié)點(diǎn)設(shè)置為紅色(即兄弟結(jié)點(diǎn)所在子樹黑色結(jié)點(diǎn)數(shù)減1,與當(dāng)前結(jié)點(diǎn)所在子樹黑色結(jié)點(diǎn)數(shù)保持平衡),此時還需要將當(dāng)前結(jié)點(diǎn)上升到父結(jié)點(diǎn)繼續(xù)處理黑色結(jié)點(diǎn)數(shù)的平衡。
//當(dāng)前結(jié)點(diǎn)上升到父結(jié)點(diǎn)后,如果該結(jié)點(diǎn)為紅色,則結(jié)束循環(huán),并將該結(jié)點(diǎn)設(shè)置為黑色即可(當(dāng)前結(jié)點(diǎn)所在子樹黑色結(jié)點(diǎn)數(shù)加1,與刪除時減1保持了平衡)。
node->isRed = false;
return root;
}
RBTreeNode* removeNode(RBTreeNode* root, RBTreeNode* node) {
if (node == NULL) {
return root;
}
RBTreeNode* y; //實(shí)際要刪除的結(jié)點(diǎn)
RBTreeNode* x; //實(shí)際要刪除結(jié)點(diǎn)的子結(jié)點(diǎn)
if (node->left == nil || node->right == nil) {
y = node;
} else {
y = getRealRemoveNode(root, node);
}
if (y->left != nil) {
x = y->left;
} else {
x = y->right;
}
//注意:當(dāng)結(jié)點(diǎn)y無左右子結(jié)點(diǎn)時,其子結(jié)點(diǎn)x為葉子結(jié)點(diǎn)nil
//刪除結(jié)點(diǎn)y
//if(x != nil) {
//注意:該判斷條件需要去掉。
//雖然葉子結(jié)點(diǎn)nil無父結(jié)點(diǎn),但是對于刪除操作,需要通過被刪除結(jié)點(diǎn)(y)的子結(jié)點(diǎn)(x),找到結(jié)點(diǎn)(y)被刪除后,子結(jié)點(diǎn)(x)的兄弟結(jié)點(diǎn)。
//而子結(jié)點(diǎn)(x)的兄弟結(jié)點(diǎn)是通過子結(jié)點(diǎn)(x)的父結(jié)點(diǎn)查找的,因此即使子節(jié)點(diǎn)(x)為葉子結(jié)點(diǎn)(nil),也需要有父指針。
x->parent = y->parent;
//}
if (y->parent == nil) { //刪除的是根結(jié)點(diǎn)
if(x == nil) { //根結(jié)點(diǎn)無子結(jié)點(diǎn)
free(root);
free(nil);
return NULL;
} else { //根結(jié)點(diǎn)有子結(jié)點(diǎn)
root = x;
}
} else { //刪除的不是根結(jié)點(diǎn)
if (y == y->parent->left) {
y->parent->left = x;
} else {
y->parent->right = x;
}
}
if (y != node) {
//替換node和y的value
//由于本來要刪除node,現(xiàn)在轉(zhuǎn)換為刪除node右結(jié)點(diǎn)的最小結(jié)點(diǎn)y,再把node的value換為y的value即可
node->value = y->value;
}
//如果刪除的結(jié)點(diǎn)是黑色,違法了性質(zhì)5,要進(jìn)行刪除修復(fù)
if (y->isRed == false) {
root = fixRemove(root, x);
}
free(y);
return root;
}
RBTreeNode* removeNodeByValue(RBTreeNode* root, int value) {
//root為指向根結(jié)點(diǎn)的指針
root = removeNode(root, findNodeByValue(root, value));
return root;
}
/*打印結(jié)點(diǎn),先序遍歷*/
void printRBTree(RBTreeNode* root) {
if (root != nil && root != NULL) {
printf("%d (%s)\n", root->value, root->isRed ? "紅" : "黑");
printRBTree(root->left);
printRBTree(root->right);
}
}
void main() {
RBTreeNode* root = NULL;
root = addNodeByValue(root, 5);
printRBTree(root);
printf("\n");
root = addNodeByValue(root, 4);
printRBTree(root);
printf("\n");
root = addNodeByValue(root, 7);
printRBTree(root);
printf("\n");
root = addNodeByValue(root, 2);
printRBTree(root);
printf("\n");
root = addNodeByValue(root, 6);
printRBTree(root);
printf("\n");
root = addNodeByValue(root, 3);
printRBTree(root);
printf("\n");
root = addNodeByValue(root, 8);
printRBTree(root);
printf("\n");
root = addNodeByValue(root, 1);
printRBTree(root);
printf("\n");
root = addNodeByValue(root, 9);
printRBTree(root);
printf("\n");
root = addNodeByValue(root, 11);
printRBTree(root);
printf("\n");
root = addNodeByValue(root, 10);
printRBTree(root);
printf("\n");
root = removeNodeByValue(root, 1);
printRBTree(root);
printf("\n");
root = removeNodeByValue(root, 2);
printRBTree(root);
printf("\n");
root = removeNodeByValue(root, 9);
printRBTree(root);
printf("\n");
root = removeNodeByValue(root, 7);
printRBTree(root);
printf("\n");
root = removeNodeByValue(root, 8);
printRBTree(root);
printf("\n");
/*
root = addNodeByValue(root, 5);
printRBTree(root);
printf("\n");
root = addNodeByValue(root, 6);
printRBTree(root);
printf("\n");
root = removeNodeByValue(root, 5);
printRBTree(root);
printf("\n");
root = removeNodeByValue(root, 6);
printRBTree(root);
printf("\n");
*/
}
紅黑樹與AVL樹的比較
- AVL樹要求任意結(jié)點(diǎn)的左右子樹的高度差的絕對值小于等于1,插入和刪除結(jié)點(diǎn)時通過結(jié)點(diǎn)旋轉(zhuǎn)保持樹的平衡。而紅黑樹則要求黑色結(jié)點(diǎn)數(shù)保持平衡,插入和刪除結(jié)點(diǎn)時通過結(jié)點(diǎn)旋轉(zhuǎn)和變色保持樹的平衡。
- AVL樹的最大高度為1.44logn。而紅黑樹的最大高度為2log(n+1),對于給定的黑色高度為N的紅黑樹,從根到葉子節(jié)點(diǎn)的最短路徑長度為N-1,最長路徑長度為2*(N-1)。
- 對于插入結(jié)點(diǎn)導(dǎo)致樹失衡的情況,紅黑樹和AVL樹都是最多2次結(jié)點(diǎn)旋轉(zhuǎn)來實(shí)現(xiàn)復(fù)衡,旋轉(zhuǎn)的量級是O(1)。
- 對于刪除結(jié)點(diǎn)導(dǎo)致樹失衡的情況,AVL樹需要維護(hù)從被刪除結(jié)點(diǎn)到根節(jié)點(diǎn)這條路徑上所有結(jié)點(diǎn)的平衡,旋轉(zhuǎn)的量級為O(logn)。而紅黑樹最多只需要旋轉(zhuǎn)3次實(shí)現(xiàn)復(fù)衡,旋轉(zhuǎn)的量級為O(1)。
- 在實(shí)際應(yīng)用中,如果搜索的次數(shù)遠(yuǎn)遠(yuǎn)大于插入和刪除的次數(shù),那么選擇AVL樹。如果搜索、插入和刪除的次數(shù)幾乎差不多,那么選擇紅黑樹。