1.红黑树
1.1 红黑树的删除,我们假定Z是被删除节点
- 1.最简单情况,Z是树的根,且树除了根节点没有其他节点,则直接删除;
- 2.Z是树的根,且树只有一个红孩子,则将根删除,将孩子节点变黑,成为新的根;
- 3.Z是红色的叶子节点,则直接删除;
- 4.Z是黑色的,非根,且只有一个红孩子,则将红孩子与爷爷节点连接,并将孩子变黑;
- 5.Z是黑色的,非根,且无孩子,则需分类讨论;
- 5.1 Z的兄弟节点是红色的,父节点和侄子节点都是黑色,需讨论Z是左孩子还是右孩子;
- 5.1.1 兄弟节点是父节点的右孩子,以父节点为支点进行左旋操作,更新兄弟节点;
- 5.1.2 兄弟节点是父节点的左孩子,以父节点为支点进行右旋操作,更新兄弟节点;
- 5.2 Z的兄弟节点是黑色的,分开讨论;
- 5.2.1 侄子全是黑色的,需要判断父节点是黑还是红;
- 5.2.1.1 父节点是红色,则将兄弟节点变为红色,将父节点变黑,结束;
- 5.2.1.2 父节点是黑色,则将兄弟节点变为红色,将父节点当作新Z来重新调整(向上找爷爷节点,向下平衡);
- 5.2.2 侄子节点左红右黑;
- 5.2.2.1 兄弟节点是父节点的右孩子,将兄弟节点变红,左侄子节点变黑,以兄弟节点为支点进行右旋操作,更新兄弟节点,进入5.2.3.1;
- 5.2.3 侄子节点左黑右红;
- 5.2.3.1 兄弟节点是父节点的右孩子,将右侄子节点变黑,父节点的颜色传给兄弟节点,父节点变黑,以父节点为支点进行左旋,结束;
- 5.2.3.2 兄弟节点是父节点的左孩子,将兄弟节点变红,右侄子节点变黑,以兄弟节点为支点进行左旋操作,更新兄弟节点,进入5.2.2.2;
- 5.2.2.2 兄弟节点是父节点的左孩子,将左侄子节点变黑,父节点的颜色传给兄弟节点,父节点变黑,以父节点为支点进行右旋,结束;
RBT* Search(RBT* p_tree, int find_num)
{
while(p_tree)
{
if(p_tree->n_value == find_num)
return p_tree;
else if(p_tree->n_value < find_num)
p_tree = p_tree->p_right;
else
p_tree = p_tree->p_left;
}
return NULL;
}
void DelNode(int del_num)
{
RBT* p_temp = NULL;
p_temp = Search(p_rbt, del_num);
if(p_temp == NULL)return;
RBT* p_flag = NULL;
if(p_temp->p_left != NULL && p_temp->p_right != NULL)
{
p_flag = p_temp;
p_temp = p_temp->p_left;
while(p_temp->p_right)
{
p_temp = p_temp->p_right;
}
}
RBT* p_node = p_temp->p_father;
}