红黑树具有以下特性:
节点颜色: 每个节点要么是红色,要么是黑色。
根节点: 根节点是黑色的。
叶子节点(NIL节点): 叶子节点是黑色的,也被称为NIL节点。它们不存储任何数据,只是作为树结构的辅助。所有指向NIL节点的指针都被认为是黑色的。
颜色限制: 不能有两个相连的红色节点,即红色节点不能相邻,每个红色节点的子节点都是黑色的。
黑高度: 从任意节点出发,到达其每个叶子节点的路径上的黑色节点数量必须相同,这被称为黑高度。这个性质保证了树的平衡。
#include<iostream>
#include<stdio.h>
#include<assert.h>
typedef enum{RED = 0,BLACK = 1} ColorType;
typedef int KeyType;
typedef struct RBNode
{
RBNode* leftchild;
RBNode* rightchild;
RBNode* parent;
ColorType color;
KeyType key;
}RBNode;
typedef struct
{
RBNode* root;
RBNode* Nil;
int cursize;
}RBTree;
RBNode* BuyNode(RBNode*parg,ColorType carg)
{
RBNode* ptr = (RBNode*)calloc(1, sizeof(RBNode));
if (ptr == nullptr) exit(EXIT_FAILURE);
ptr->color = carg;
ptr->parent = parg;
return ptr;
}
void FreeNode(RBNode* ptr)
{
free(ptr);
}
void InitRBTree(RBTree* ptree)
{
assert(ptree != nullptr);
ptree->Nil = BuyNode(nullptr, BLACK);
ptree->root = ptree->Nil;
ptree->cursize = 0;
}
RBNode* FindValue(RBTree* ptree, const KeyType kx)
{
assert(ptree != nullptr);
RBNode* p = ptree->root;
while (p != ptree->Nil && p->key != kx)
{
p = kx < p->key ? p->leftchild : p->rightchild;
}
return p;
}
RBNode* First(RBTree *ptree , RBNode* ptr)
{
assert(ptree != nullptr && ptr != nullptr);
while (ptr != ptree->Nil && ptr->leftchild != ptree->Nil)
{
ptr = ptr->leftchild;
}
return ptr;
}
RBNode* Next(RBTree* ptree, RBNode* ptr)
{
if (ptr == ptree->Nil || ptr == nullptr) return ptree->Nil;
if (ptr->rightchild != ptree->Nil)
{
return First(ptree, ptr->rightchild);
}
else
{
RBNode* pa = ptr->parent;
while (pa != nullptr && pa->leftchild != ptr)
{
ptr = pa;
pa = ptr->parent;
}
return pa;
}
}
void NiceInOrder(RBTree* ptree)
{
assert(ptree != nullptr);
for (RBNode* ptr = First(ptree, ptree->root);!(ptr == nullptr || ptr == ptree->Nil); ptr = Next(ptree, ptr))
{
printf("Color: %s Key: %3d\n",((ptr->color==RED)?"红色":"黑色"), ptr->key);
}
printf("\n");
}
RBNode* RotateLeft(RBTree* ptree, RBNode* ptr)
{
assert(ptree != nullptr && ptr != nullptr);
RBNode* newroot = ptr->rightchild;//1
newroot->parent = ptr->parent;
ptr->rightchild = newroot->leftchild;//2
if (newroot->leftchild != ptree->Nil)//是否有左孩子
{
newroot->leftchild->parent = ptr;
}
newroot->leftchild = ptr;//3
RBNode* pa = ptr->parent;
if (pa == nullptr)//ptr是否为根
{
ptree->root = newroot;
}
else
{
if (pa->leftchild == ptr)
{
pa->leftchild = newroot;
}
else
{
pa->rightchild = newroot;
}
}
ptr->parent = newroot;
return newroot;
}
RBNode* RotateRight(RBTree* ptree, RBNode* ptr)
{
assert(ptree != nullptr && ptr != nullptr);
RBNode* newroot = ptr->leftchild;//1
newroot->parent = ptr->parent;
ptr->leftchild = newroot->rightchild;//2
if (newroot->rightchild != ptree->Nil)//无右孩子
{
newroot->rightchild->parent = ptr;
}
newroot->rightchild = ptr;//3
RBNode* pa = ptr->parent;
if (pa == nullptr)//ptr是否为根
{
ptree->root = newroot;
}
else
{
if (pa->leftchild == ptr)
{
pa->leftchild = newroot;
}
else
{
pa->rightchild = newroot;
}
}
ptr->parent = newroot;
return newroot;
}
void Insert(RBTree* ptree, RBNode* pa, const KeyType kx)
{
RBNode* s = BuyNode(pa, RED);
s->key = kx;
s->leftchild = ptree->Nil;
s->rightchild = ptree->Nil;
if (pa == nullptr)//空树
{
ptree->root = s;
}
else
{
if (pa->key > s->key)
{
pa->leftchild = s;
}
else
{
pa->rightchild = s;
}
}
RBNode* p = s;
while (p != ptree->root && p->parent->color == RED)
{
if (p->parent == p->parent->parent->rightchild)//判断插入节点为右孩子
{
RBNode* left = p->parent->parent->leftchild;
if (left->color == RED)//着色来调整
{
p->parent->color = BLACK;
p->parent->parent->color = RED;
left->color = BLACK;
p = p->parent->parent;
}
else
{
if (p == p->parent->leftchild)//折线进行双旋
{
p = p->parent;
RotateRight(ptree, p);
}
p->parent->color = BLACK;
p->parent->parent->color = RED;
RotateLeft(ptree, p->parent->parent);
}
}
else
{
RBNode* right = p->parent->parent->rightchild;
if (right->color == RED)//着色来调整
{
p->parent->color = BLACK;
p->parent->parent->color = RED;
right->color = BLACK;
p = p->parent->parent;
}
else
{
if (p == p->parent->rightchild)//折线进行双旋
{
p = p->parent;
RotateLeft(ptree, p);
}
p->parent->color = BLACK;
p->parent->parent->color = RED;
RotateRight(ptree, p->parent->parent);
}
}
}
ptree->root->color = BLACK;
}
bool Insert_Item(RBTree* ptree, const KeyType kx)
{
assert(ptree != nullptr);
RBNode* p = ptree->root;
RBNode* pa = nullptr;
while (p != ptree->Nil && p->key != kx)
{
pa = p;
p = kx < p->key ? p->leftchild : p->rightchild;
}
if (p != ptree->Nil) return false;
Insert(ptree, pa, kx);
ptree->cursize += 1;
return true;
}
int main()
{
KeyType ar[] = { 16,3,7,11,9,26,18,14,15,45,34,50 };
int len = sizeof(ar) / sizeof(ar[0]);
RBTree tree;
InitRBTree(&tree);
for (int i = 0; i < len; ++i)
{
Insert_Item(&tree, ar[i]);
}
NiceInOrder(&tree);
return 0;
}