//-------------平衡树-----------------------------
//树的高度限制在结点数的对数范围之内
//红黑树插入算法
void rb_insert(element_type x)
{
检索树插入算法;
x标注为红色;
p指向x;
while(1){
if(p是根){p改为黑色;return;} //情况1
if(f为黑色){return;} //情况2
f是p之父,g是f之父;
//p不是根,p之父为红色并且不为根
if(f是g的左儿子){
用q是g的右儿子; //f和q互为兄弟
if(q是红色){f和q改为黑色;g改为红色;p指向g;continue;}
//q为黑色
if(p是f的右儿子){在f点左旋,并调整指针(f与p互换)}//都改成左儿子
f改黑色,g改红色;
在g点右旋;
return;//结束回溯
}
else{//f是g的右儿子
用q是g的左儿子;
if(q是红色){f和q改为黑色;g改为红色;p指向g;continue;}
//q为黑色
if(p是f的左儿子){在f点右旋,并调整指针(f与p互换)}//都改成右儿子
f改黑色,g改红色;
在g点左旋;
return;//结束回溯
}
}
}
//红黑删除算法
void rb_delete(element_type x){
找到删除结点x,f指向x;
if(x有两个儿子){找x中序前驱y;用y的结点值代替x的节点值;平且f指向y}
//f指向的结点被删除,f至多有一个儿子
if(f的左儿子不空){p指向f的左儿子;}
else{p指向f的右儿子;}
if(f是根){使p作根,并将p标为黑色;return} //特色情况 当删除根的时候
else 让p代替f作为其父g的儿子; //这会p已经代替f f为了g点平衡 会有兄弟
if(f是红色) {return}; //如果被删除的是红色,不要回溯
if(f是黑,p是红){将p标为黑色,return}
// 至此,f和p都是黑色
while(p不是根,p是黑的){
if(p是左儿子){
q指向p的兄弟;
if(q是红){q改为黑色;将p之父改为红色;在p之父处左旋;将q重新指向p的新右兄弟;} //情况1
if(q的左右儿子都是黑色){将q改为红色;p指向其父;continue;} //情况2
else{
if(q的右儿子是黑色,左儿子是红色) //情况3
{ q的左儿子变黑,将q变红;
q点右旋;将q重新指向p的新右兄弟
}
p之父的颜色赋给q; //情况4
将p之父的颜色改为黑色,将q的右儿子改黑色;
在p之父处左旋;
p指向根;
}
}
//p为右儿子
else{
q指向p的兄弟;
if(q是红){q改为黑色;将p之父改为红色;在p之父处右旋;将q重新指向p的新左兄弟;} //情况1
if(q的左右儿子都是黑色){将q改为红色;p指向其父;continue;} //情况2
else{
if(q的左儿子是黑色,右儿子是红色) //情况3
{ q的右儿子变黑,将q变红;
q点右旋;将q重新指向p的新左兄弟
}
p之父的颜色赋给q; //情况4
将p之父的颜色改为黑色,将q的左儿子改黑色;
在p之父处右旋;
p指向根;
}
}
}
p该为黑色;
return;
}