红黑树学习笔记
红黑树是一种二叉查找树,接近平衡的,确保没有一条路径比其他路径长2倍。
性质:
1)每个结点要么是红的,要么是黑的。
2)根结点是黑的。
3)每个叶子结点,即空结点是黑的,叶子是NIL结点
4)如果一个结点是红的,那么他的两个孩子是黑的
5)对每个结点,从该结点到其子孙结点的所有路径包含相同数目的的黑结点
性质4暗示着任何一个简单路径上不能有两个毗连的红色节点,这样,最短的可能路径全是黑色节点,最长的可能路径有交替的红色和黑色节点。同时根据性质5知道:所有最长的路径都有相同数目的黑色节点,这就表明了没有路径能多于任何其他路径的两倍长。
插入操作:
1)查找要插入的位置,O(n),其操作跟二叉查找树一样。
2)将新结点的color设置为red
3)自下而上调整树为红黑树
插入情况:
1)新的结点N位于树的根上,没有父节点:
node n;
n->color = red;
void inster_case1(node n)
{
if(n->parent == NULL)
n->color = black;
else
insert_case2(n);
}
2)父亲结点为黑色P:
void inster_case2(node n)
{
if(n->parent->color == black)
return ;
else
inster_case3(n);
}
3)父节点P,叔叔U都为红色:
void insert_case3(node n)
{
if(uncle(n)!= NULL && uncle(n)->color == red)
{
n->parent->color = black;
uncle(n)->color = black;
grandparent(n)->color = red;
inster_case1(grandparent(n));
}
else
inster_case4(n);
}
4)父节点为红色,叔叔为黑色或nil
1.该结点是父节点的右孩子,父节点是祖父的左孩子:
void insert_case4(node n)
{
if(n== n->parent->right && n->parent == greandparent(n) ->left)
{
rotate_left(n->parent);
n = n->left;
}
else if(n == n->parent->left && n->parent == grandparent(n)->right)
{
rotate_left(n->parnt);
n = n->right;
}
inster_case5(n);
}
2.该结点是父节点的左孩子,父节点是祖父的左孩子:
void inster_case5(node n)
{
n->parent->color = black;
grandparent(n) -> color = red;
if(n== n->parnet ->left && n->parent == grandparnet(n) - >left)
rotate_right(grandparnet(n));
else
rotate_left(grandparent(n));
}