花了好几天的业余时间,看文章,总算是用C实现了一遍红黑树,主要仍是本身C语言水平不够高,调试断点浪费了很多时间,闲话少说node
//这里偷懒就应0表明黑色,1表明红色了 typedef struct RBTreeNode { int data; //数据域 int color; //0黑色 1红色 struct RBTreeNode *parent;//父亲结点 struct RBTreeNode *left; //左子结点 struct RBTreeNode *right; //右子结点 } RBTreeNode;
//这里打印了节点的颜色和父节点 void preOrderTraverse(RBTreeNode *root) { if (root != NULL) { if (root->parent != NULL) { printf("%d color: %d parent:%d\n", root->data, root->color, root->parent->data); }else{ printf("%d color: %d\n", root->data, root->color); } preOrderTraverse(root->left); preOrderTraverse(root->right); } }
跟AVL树差很少,多了parent相关的操做测试
/** * 左旋 * parent parent * 8 12 * 4 12 8 50 * 9 50 => 4 9 70 * 70 */ RBTreeNode *left_rotation(RBTreeNode *root) { struct RBTreeNode *new_root; new_root = root->right; root->right = new_root->left; //将9的父亲设置为老的root 即8 if (new_root->left != NULL) { new_root->left->parent = root; } //新root的parent即老parent new_root->parent = root->parent; //而后处理老root的parent if (root->parent == NULL) { //老root是根节点 new_root->parent = NULL; }else{ //判断父亲左右 if (new_root->parent->left == root) { new_root->parent->left = new_root; }else{ new_root->parent->right = new_root; } } root->parent = new_root; new_root->left = root; return new_root; }
/** * 右旋 * 8 4 * 4 12 2 8 * 2 6 => 1 6 12 * 1 */ RBTreeNode *right_rotation(RBTreeNode *root) { struct RBTreeNode *new_root; new_root = root->left; root->left = new_root->right; //将6的父亲设置为老的root 即8 if (new_root->right != NULL) { new_root->right->parent = root; } //新root的parent即老parent new_root->parent = root->parent; //而后处理老root的parent if (root->parent == NULL) { //老root是根节点 new_root->parent = NULL; }else{ //判断父亲左右 if (new_root->parent->left == root) { new_root->parent->left = new_root; }else{ new_root->parent->right = new_root; } } new_root->right = root; root->parent = new_root; // printf("***本身right_rotation***: \n"); // printfNode(new_root); // printf("***左***: \n"); // printfNode(new_root->left); // printf("***右***: \n"); // printfNode(new_root->right); return new_root; }
/** * 1.插入的只有一个根节点 * * 8(R) => 8(B) * * 2.1父节点是黑色,啥也不用干 * 8(B) * / => 不变 * 4(R) * * 2.2 父节点是红色,祖父必定是黑色啦,看叔叔是啥颜色 * * 2.2.1 父节点是祖父节点的左节点 * * 2.2.1.1若是叔叔也是红色 * 将父节点,叔节点设为黑色,将祖父节点设为红色,将祖父节点设为“当前节点”(红色节点);即,以后递归继续对“当前节点”进行操做 * * 8(B) 8(R) 8(B) * / \ / \ / \ * 4(R) 12(R) => 4(B) 12(B) => 4(B) 12(B) * / / / * 2(R) 2(R) 2(R) * * 2.2.1.2若是叔叔不存在或是黑色 * 2.2.1.2.1新节点在左子树 * 父节点设为黑色,将祖父节点设为红色,对祖父节点右旋 * * 8(B) 8(R) 8(B) * / \ 着色 / \ 对4右旋 / \ * 4(B) 12(B) => 4(R) 12(B) => 2(B) 12(B) * / / / \ * 2(R) 2(B) 1(R) 4(R) * / / * 1(R) 1(R) * * 2.2.1.2.2新节点在右子树 * root与父节点交换 并把父节点设为新root的左节点,即转化为2.2.1.2.1,处理如上 * * 8(B) 8(B) 8(B) 8(B) * / \ 交换 / \ 着色 / \ 对4右旋 / \ * 4(B) 12(B) => 4(B) 12(B) => 4(R) 12(B) => 3(B) 12(B) * / / / / \ * 2(R) 3(R) 3(B) 2(R) 4(R) * \ / / * 3(R) 2(R) 2(R) * * * * 2.2.2 父节点是祖父节点的右节点 * 2.2.2.1若是叔叔也是红色 * 将父节点,叔节点设为黑色,将祖父节点设为红色,将祖父节点设为“当前节点”(红色节点);即,以后递归继续对“当前节点”进行操做 * * 8(B) 8(R) 8(B) * / \ / \ / \ * 4(R) 12(R) => 4(B) 12(B) => 4(B) 12(B) * \ \ \ * 20(R) 20(R) 20(R) * * 2.2.2.2若是叔叔不存在或是黑色(这里的绘图简化些,其实都同样的) * 2.2.2.2.1新节点在左子树 * root与父节点交换 并把父节点设为新root的右节点,即转化为2.2.2.2.2 * 8(B) 8(B) 8(R) 10(B) * \ 交换 \ 着色 \ 对8右旋 / \ * 12(R) => 10(R) => 10(B) => 8(R) 12(R) * / \ \ * 10(R) 12(R) 12(R) * * 2.2.2.2.2新节点在右子树 * 将父节点设为黑色 将祖父节点设为红色 左旋 * * 8(B) 8(R) 12(B) * \ 着色 \ 对8左旋 / \ * 12(B) => 12(B) => 8(R) 20(R) * \ \ * 20(R) 20(R) * * */
RBTreeNode *rebalance3(RBTreeNode *root, RBTreeNode *rootNode)//返回新的根节点 { //1 插入根节点,只需置黑便可 if (root->parent == NULL) { root->color = 0; } //2 有父节点 if (root->parent != NULL) { //2.1 父节点是黑色,啥也不用干 if (root->parent->color == 0) { //do nothing }else{ //2.2 父节点是红色,祖父必定是黑色啦,看叔叔是啥颜色 RBTreeNode *parent, *gparent, *uncle; parent = root->parent; gparent = root->parent->parent; int return_flag = 0; if (gparent == rootNode) { return_flag = 1; } //先判断父节点是祖父节点的左节点仍是右节点,即叔叔节点是啥 //2.2.1 父节点是祖父节点的左节点 if (parent == gparent->left) { uncle = gparent->right; //2.2.1.1若是叔叔也是红色 if (uncle != NULL && uncle->color == 1) { //1.将父节点设为黑色 parent->color = 0; //2.将叔节点设为黑色 uncle->color = 0; //3.将祖父节点设为红色 gparent->color = 1; //4.将祖父节点设为“当前节点”(红色节点);即,以后继续对“当前节点”进行操做 return rebalance3(gparent, rootNode); }else{ //2.2.1.2若是叔叔黑色 或不存在 //2.2.1.2.1 root是左节点 if (root == parent->left) { //1.将父节点设为黑色 parent->color = 0; //2.将祖父节点设为红色 gparent->color = 1; gparent = right_rotation(gparent); }else{ //2.2.1.2.2 root是右节点 //1.root与父节点交换 并把父节点设为新root的左节点,即转化为2.2.1.2.1 gparent->left = root; root->parent = gparent; root->left = parent; parent->parent = root; parent->right = NULL; return rebalance3(parent, rootNode); } } }else{ //2.2.2 父节点是祖父节点的右节点 uncle = gparent->left; //2.2.2.1若是叔叔也是红色 if (uncle != NULL && uncle->color == 1) { //1.将父节点设为黑色 parent->color = 0; //2.将叔节点设为黑色 uncle->color = 0; //3.将祖父节点设为红色 gparent->color = 1; //4.将祖父节点设为“当前节点”(红色节点);即,以后继续对“当前节点”进行操做 return rebalance3(gparent, rootNode); }else{ //2.2.2.2若是叔叔黑色 或不存在 //2.2.2.2.1 root是左节点 if (root == parent->left) { //1.root与父节点交换 并把父节点设为新root的左节点,即转化为2.2.2.2.2 gparent->right = root; root->parent = gparent; root->right = parent; parent->parent = root; parent->left = NULL; return rebalance3(parent, rootNode); }else{ //2.2.2.2.2 root是右节点 //1.将父节点设为黑色 parent->color = 0; //2.将祖父节点设为红色 gparent->color = 1; gparent = left_rotation(gparent); } } } if (return_flag == 1) { return gparent; } } } return rootNode; }
RBTreeNode *getNode(int data, RBTreeNode *parent) { struct RBTreeNode *node; node = (struct RBTreeNode *)malloc(sizeof(struct RBTreeNode)); if (node == NULL) { printf("malloc error \n"); return NULL; } node->data = data; node->parent= parent; node->color = 1; node->right = NULL; node->left = NULL; if (parent == NULL) { node->color = 0; } RBTreeEndNode = node; return node; } RBTreeNode *insert(RBTreeNode *root, int data, RBTreeNode *parent) { if (NULL == root) { return getNode(data, parent); } if (data >= root->data) { root->right = insert(root->right, data, root); }else{ root->left = insert(root->left, data, root); } return root; }
RBTreeNode *inserRB(RBTreeNode *root, int data, RBTreeNode *parent) { root = insert(root,data,parent); return rebalance3(RBTreeEndNode,root); }
int main() { struct RBTreeNode *node; //2.2.1.1 测试用例 node = NULL; node = inserRB(node, 8, NULL); node = inserRB(node, 4, NULL); node = inserRB(node, 12, NULL); node = inserRB(node, 2, NULL); printf("***2.2.1.1 测试用例 前序***: \n"); preOrderTraverse(node); //2.2.1.2.1 测试用例 node = NULL; node = inserRB(node, 8, NULL); node = inserRB(node, 4, NULL); node = inserRB(node, 12, NULL); node = inserRB(node, 2, NULL); node = inserRB(node, 1, NULL); printf("***2.2.1.2.1 测试用例 前序***: \n"); preOrderTraverse(node); //2.2.1.2.2 测试用例 node = NULL; node = inserRB(node, 8, NULL); node = inserRB(node, 4, NULL); node = inserRB(node, 12, NULL); node = inserRB(node, 2, NULL); node = inserRB(node, 3, NULL); printf("***2.2.1.2.2 测试用例 前序***: \n"); preOrderTraverse(node); //2.2.2.1 测试用例 node = NULL; node = inserRB(node, 8, NULL); node = inserRB(node, 4, NULL); node = inserRB(node, 12, NULL); node = inserRB(node, 20, NULL); printf("***2.2.2.1 测试用例 前序***: \n"); preOrderTraverse(node); //2.2.2.2.1 测试用例 node = NULL; node = inserRB(node, 8, NULL); node = inserRB(node, 12, NULL); node = inserRB(node, 10, NULL); printf("***2.2.2.2.1 测试用例 前序***: \n"); preOrderTraverse(node); //2.2.2.2.2 测试用例 node = NULL; node = inserRB(node, 8, NULL); node = inserRB(node, 12, NULL); node = inserRB(node, 20, NULL); printf("***2.2.2.2.2 测试用例 前序***: \n"); preOrderTraverse(node); }
测试结果:spa
*删除 * *1.没有左右节点 * * 1.1被删除节点是红色,直接删除便可 * * 8(B) 8(B) * / => * 4(R) * * 1.2被删除节点是黑色,破坏了平衡性 须要从新平衡 * * 1.2.1被删除节点在父节点的左数上 * * 1.2.1.1兄弟节点是黑色, * * 1.2.1.1.1 兄弟节点是黑色,且有一个右节点,右节点必然是红色 * parent parent parent * | | | * 8(可红可黑) 把父节点颜色赋值给14 8(可红可黑) 12(B) * / \ 删除4 着色 \ 对8左旋 / \ * 4(B) 12(B) => 12(B) => 8(可红可黑) 14(可红可黑) 最终保持黑色节点数量依旧是1或者2个 * \ \ * 14(R)必然是红色 14(可红可黑,8是啥色 这里就啥色,下同) * * 1.2.1.1.2 兄弟节点是黑色,且有一个左节点,左节点必然是红色 * parent parent parent * | 把父节点颜色赋值给兄弟节点 | | * 8(可红可黑) 相似插入时候如右图 兄左置黑 8(可红可黑) 10(B) * / \ 删除4 着色 转变为1.2.1.1 \ 对8左旋 / \ * 4(B) 12(B) => 10(B) => 8(可红可黑) 12(可红可黑) 最终保持黑色节点数量依旧是1或者2个 * / \ * 10(R)必然是红色 12(可红可黑) * * 1.2.1.1.3 兄弟节点是黑色,且有俩节点,必然都是红色 * parent parent parent * | 把父节点颜色赋值给兄弟节点 | | * 8(可红可黑) 把兄弟节点的右节点置黑 8(黑) 12(可红可黑) * / \ 把父节点置黑 删除4 \ 对8左旋 / \ * 4(B) 12(B) => 12(可红可黑) => 8(B) 14(B) 最终保持黑色节点数量依旧是1或者2个 * / \ / \ \ * 10(R) 14(R)必然都是红色 10(R) 14(B) 10(R) * 1.2.1.1.4 兄弟节点是黑色,且没有节点 黑色路径必然要-1了 递归 * ps:这个存疑 1.理论上插入时候每次自平衡不应有这个状况;2.即便有这个状况,那删除自身后,也不影响平衡啊 * * (此处例外,不是删除4,而是删除10节点) * parent parent parent * | | | * 8(可红可黑) 删除10(黑) 8(可红可黑) 8(可红可黑) * / \ 把14置红 下一步rebalance / \ rebalance / \ * 4(B) 12(R) => 4(B) 12(R) => 4(B) 12(B) 最终保持黑色节点数量依旧是1或者2个 * / \ \ \ * 10(B) 14(B) 14(R) 14(R) * * 1.2.1.2兄弟节点是红色 * 1.2.1.2.1 兄弟节点是红色,父节点必定是黑色,它必定有俩黑色子节点 * parent parent parent * | | | * 8(B) 兄弟节点置黑,兄弟左节点置红 8(B) 12(B) * / \ 删除4 着色 \ 对8左旋 / \ * 4(B) 12(R) => 12(B) => 8(B) 14(B) 最终保持黑色节点数量依旧是2个 * / \ / \ \ * 10(B) 14(B)必然是黑色 10(R) 14(B) 10(R) * * 1.2.2被删除节点在父节点的右数上 * * 1.2.2.1兄弟节点是黑色 * * 1.2.2.1.1 兄弟节点是黑色,且有一个左节点,左节点必然是红色 跟 1.2.1.1.1互为镜像 * parent parent parent * | | | * 8(可红可黑) 把父节点颜色赋值给3 8(可红可黑) 4(B) * / \ 删除12 着色 / 对8右旋 / \ * 4(B) 12(B) => 4(B) => 3(可红可黑) 8(可红可黑) 最终保持黑色节点数量依旧是1或者2个 * / / * 3(R)必然是红色 3(可红可黑) * * 1.2.2.1.2 兄弟节点是黑色,且有一个左节点,左节点必然是红色 * parent parent parent * | 把父节点颜色赋值给兄弟节点 | | * 8(可红可黑) 相似插入时候如右图 兄右置黑 8(可红可黑) 5(B) * / \ 删除12 着色 转变为1.2.2.1.1 / 对8右旋 / \ * 4(B) 12(B) => 5(B) => 4(可红可黑) 8(可红可黑) 最终保持黑色节点数量依旧是1或者2个 * \ / * 5(R)必然是红色 4(可红可黑) * * 1.2.2.1.3 兄弟节点是黑色,且有俩节点,必然都是红色 * parent parent parent * | 把父节点颜色赋值给兄弟节点 | | * 8(可红可黑) 把兄弟节点的左节点置黑 8(B) 4(可红可黑) * / \ 把父节点置黑 删除12 / 对8右旋 / \ * 4(B) 12(B) => 4(可红可黑) => 1(B) 8(B) 最终保持黑色节点数量依旧是1或者2个 * / \ / \ / * 1(R) 5(R)必然都是红色 1(R) 5(R) 5(R) * * 1.2.2.1.4 兄弟节点是黑色,且没有节点 黑色路径必然要-1了 递归 * ps:这个存疑 1.理论上插入时候每次自平衡不应有这个状况;2.即便有这个状况,那删除自身后,也不影响平衡啊 * * (此处例外,不是删除12,而是删除5节点) * parent parent parent * | | | * 8(可红可黑) 删除5(黑) 8(可红可黑) 8(可红可黑) * / \ 把1置红 下一步rebalance / \ rebalance / \ * 4(R) 12(B) => 4(R) 12(B) => 4(B) 12(B) 最终保持黑色节点数量依旧是1或者2个 * / \ / / * 1(B) 5(B)必然都是黑色 1(R) 1(R) * * 1.2.2.2兄弟节点是红色 * 1.2.2.2.1 兄弟节点是红色,父节点必定是黑色,它必定有俩黑色子节点 * parent parent parent * | | | * 8(B) 兄弟节点置黑,兄弟右节点置红 8(B) 4(B) * / \ 删除12 着色 / 对8右左旋 / \ * 4(R) 12(B) => 4(B) => 1(B) 8(B) 最终保持黑色节点数量依旧是2个 * / \ / \ / * 1(B) 5(B)必然是黑色 1(B) 5(R) 5(R) * *2. 只有左节点 * parent parent * | | * 8(可红可黑) 1的值赋给4 8(可红可黑) * / \ 删除1 着色 / \ * 4(B) 12(B) => 1(B) 12(B) 最终保持黑色节点数量依旧是2个 * / * 1(R) *4. 只有右节点 同上 *5. 左右都有 * //后继节点:删除节点的右子树中的最小节点,即右子树中最左节点。 * //前驱节点:删除节点的左子树中最大节点,即左子树中最右节点。 * 使用前驱or后继代替当前删除节点,而后删除替代结点,把情形转化为1,2,3的状况 */
RBTreeNode *FindMin(RBTreeNode *root) { if (NULL == root) { return NULL; } if (root->left == NULL) { return root; }else{ return FindMin(root->left); } } RBTreeNode *Delete(RBTreeNode *root, int target, RBTreeNode *rootNode) { if (NULL == root) { return NULL; } if (target > root->data) { rootNode = Delete(root->right, target, rootNode); }else if(target < root->data){ rootNode = Delete(root->left, target, rootNode); }else{ //根节点 if (root->parent == NULL) { return NULL;//删除自身 } RBTreeNode *parent, *brother; parent = root->parent; int root_flag = 0; if (parent == rootNode) { root_flag = 1; } //1.没有左右节点 if (root->left == NULL && root->right == NULL) { //1.1被删除节点是红色,直接删除便可 if (root->color == 1) { if (root == parent->left){ parent->left = NULL; }else{ parent->right = NULL; } root = NULL;//删除自身 }else{ //1.2被删除节点是黑色,必定右兄弟节点 破坏了平衡性 须要从新平衡 //1.2.1被删除节点在父节点的左数上 if (root == parent->left) { root = NULL; parent->left = NULL;//删除自身 brother = parent->right; //1.2.1.1兄弟节点是黑色 if (brother->color == 0) { //1.2.1.1.1 兄弟节点是黑色,且有一个右节点,右节点必然是红色 if (brother->right != NULL && brother->left == NULL) { //把父亲颜色赋值给兄弟节点的右节点 brother->right->color = parent->color; parent = left_rotation(parent); }else if (brother->right == NULL && brother->left != NULL) //1.2.1.1.2 兄弟节点是黑色,且有一个左节点,左节点必然是红色 { //把父亲颜色赋值给兄弟节点 brother->color = parent->color; parent->right = brother->left; brother->parent = brother->left; brother->left->parent = parent; brother->left->right = brother; brother->left = NULL; parent = left_rotation(parent); }else if (brother->right != NULL && brother->left != NULL) { //1.2.1.1.3 兄弟节点是黑色,且有俩节点,必然都是红色 //把父亲颜色赋值给兄弟节点 brother->color = parent->color; //把兄弟节点的右节点置黑 //把父节点置黑 brother->right->color = 0; parent->color = 0; parent = left_rotation(parent); }else{ //1.2.1.1.4 兄弟节点是黑色,且没有节点 黑色路径必然要-1了 递归 //ps:这个存疑 1.理论上插入时候每次自平衡不应有这个状况;2.即便有这个状况,那删除自身后,也不影响平衡啊 //parent->right->color = 1; //return rebalance3(parent->right,rootNode); } }else{ //1.2.1.2兄弟节点是红色,父节点必定是黑色,它必定有俩黑色子节点 //兄弟节点置黑,兄弟左节点置红 brother->color = 0; brother->left->color = 1; parent = left_rotation(parent); } }else{ //1.2.2被删除节点在父节点的右数上 root = NULL; parent->right = NULL;//删除自身 brother = parent->left; //1.2.2.1 兄弟节点是黑色 if (brother->color == 0) { //1.2.2.1.1 兄弟节点是黑色,且有一个左节点,左节点必然是红色 跟1.2.1.1.1是镜像关系 if (brother->right == NULL && brother->left != NULL) { //把父亲颜色赋值给兄弟节点的左节点 brother->left->color = parent->color; parent = right_rotation(parent); }else if(brother->right != NULL && brother->left == NULL) //1.2.2.1.2 兄弟节点是黑色,且有一个右节点,右节点必然是红色 跟1.2.1.1.2是镜像关系 { parent->left = brother->right; brother->color = parent->color; brother->parent = brother->right; brother->right->parent = parent; brother->right->left = brother; brother->right = NULL; parent = right_rotation(parent); }else if(brother->right != NULL && brother->left != NULL) //1.2.2.1.3 兄弟节点是黑色,且有俩节点,必然都是红色 跟1.2.1.1.3是镜像关系 { brother->left->color = 0; brother->color = parent->color; parent = right_rotation(parent); }else{ //1.2.2.1.4 兄弟节点是黑色,且没有节点 黑色路径必然要-1了 递归 //ps:这个存疑 1.理论上插入时候每次自平衡不应有这个状况;2.即便有这个状况,那删除自身后,也不影响平衡啊 //do nothng // parent->left->color = 1; // return rebalance3(parent->left,rootNode); } }else{ //1.2.2.2兄弟节点是红色,父节点必定是黑色,它必定有俩黑色子节点 //兄弟节点置黑,兄弟右节点置红 brother->color = 0; brother->right->color = 1; parent = right_rotation(parent); } } } }else if (root->left != NULL && root->right == NULL) //2.只有左节点 该左节点必然是红色,那root必定是黑色,root值替换为左节点的值,删除左节点 { root->data = root->left->data; root->left = NULL; }else if (root->right != NULL && root->left == NULL) //3.只有右节点 该右节点必然是红色,那root必定是黑色,root值替换为右节点的值,删除右节点 { root->data = root->right->data; root->right = NULL; }else{ //4.左右都有的状况 //后继节点:删除节点的右子树中的最小节点,即右子树中最左节点。 //前驱节点:删除节点的左子树中最大节点,即左子树中最右节点。 //4.1使用后继节点做为代替结点 RBTreeNode *min = FindMin(root->right); root->data = min->data; rootNode = Delete(min, min->data, rootNode); } if (root_flag == 1) { return parent; } } return rootNode; }
int main() { struct RBTreeNode *node; //1.1 测试用例 node = NULL; node = inserRB(node, 8, NULL); node = inserRB(node, 4, NULL); node = Delete(node, 4, node); printf("***1.1 测试用例 前序***: \n"); preOrderTraverse(node); //1.2.1.1.1 测试用例 node = NULL; node = inserRB(node, 8, NULL); node = inserRB(node, 4, NULL); node = inserRB(node, 12, NULL); node = inserRB(node, 14, NULL); node = Delete(node, 4, node); printfNode(node); printf("***1.2.1.1.1 测试用例 前序***: \n"); preOrderTraverse(node); //1.2.1.1.2 测试用例 node = NULL; node = inserRB(node, 8, NULL); node = inserRB(node, 4, NULL); node = inserRB(node, 12, NULL); node = inserRB(node, 10, NULL); node = Delete(node, 4, node); printfNode(node); printf("***1.2.1.1.2 测试用例 前序***: \n"); preOrderTraverse(node); //1.2.1.1.3 测试用例 node = NULL; node = inserRB(node, 8, NULL); node = inserRB(node, 4, NULL); node = inserRB(node, 12, NULL); node = inserRB(node, 10, NULL); node = inserRB(node, 14, NULL); node = Delete(node, 4, node); printfNode(node); printf("***1.2.1.1.3 测试用例 前序***: \n"); preOrderTraverse(node); //1.2.1.1.4 测试用例 存疑 node = NULL; node = inserRB(node, 8, NULL); node = inserRB(node, 4, NULL); node = inserRB(node, 12, NULL); node = inserRB(node, 10, NULL); node = inserRB(node, 14, NULL); //这里须要特殊处理,由于8,4,12,10,14生成的红黑树不符合1.2.1.1.4的测试场景,处理后依然是红黑树 // 8(B) 8(B) // / \ 处理后 / \ // 4(B) 12(B) => 4(B) 12(R) // / \ / \ // 10(R) 14(R) 10(B) 14(B) node->right->color = 1; node->right->right->color = 0; node->right->left->color = 0; node = Delete(node, 10, node); printf("***1.2.1.1.4 测试用例 前序***: \n"); preOrderTraverse(node); //1.2.1.2.1 测试用例 存疑 node = NULL; node = inserRB(node, 8, NULL); node = inserRB(node, 4, NULL); node = inserRB(node, 12, NULL); node = inserRB(node, 10, NULL); node = inserRB(node, 14, NULL); //这里须要特殊处理,由于8,4,12,10,14生成的红黑树不符合1.2.1.1.4的测试场景,处理后依然是红黑树 // 8(B) 8(B) // / \ 处理后 / \ // 4(B) 12(B) => 4(B) 12(R) // / \ / \ // 10(R) 14(R) 10(B) 14(B) node->right->color = 1; node->right->right->color = 0; node->right->left->color = 0; node = Delete(node, 4, node); printf("***1.2.1.2.1 测试用例 前序***: \n"); preOrderTraverse(node); //1.2.2.1.1 测试用例 跟1.2.1.1.1是镜像关系 node = NULL; node = inserRB(node, 8, NULL); node = inserRB(node, 4, NULL); node = inserRB(node, 12, NULL); node = inserRB(node, 3, NULL); node = Delete(node, 12, node); printfNode(node); printf("***1.2.2.1.1 测试用例 前序***: \n"); preOrderTraverse(node); //1.2.2.1.2 测试用例 跟1.2.1.1.2是镜像关系 node = NULL; node = inserRB(node, 8, NULL); node = inserRB(node, 4, NULL); node = inserRB(node, 12, NULL); node = inserRB(node, 5, NULL); node = Delete(node, 12, node); printfNode(node); printf("***1.2.2.1.1 测试用例 前序***: \n"); preOrderTraverse(node); //1.2.2.1.3 测试用例 跟1.2.1.1.2是镜像关系 node = NULL; node = inserRB(node, 8, NULL); node = inserRB(node, 4, NULL); node = inserRB(node, 12, NULL); node = inserRB(node, 1, NULL); node = inserRB(node, 5, NULL); node = Delete(node, 12, node); printf("***1.2.2.1.3 测试用例 前序***: \n"); preOrderTraverse(node); //1.2.2.1.4 测试用例 跟1.2.1.1.4是镜像关系 存疑 node = NULL; node = inserRB(node, 8, NULL); node = inserRB(node, 4, NULL); node = inserRB(node, 12, NULL); node = inserRB(node, 1, NULL); node = inserRB(node, 5, NULL); node = Delete(node, 5, node); printf("***1.2.2.1.4 测试用例 前序***: \n"); preOrderTraverse(node); //1.2.2.2 测试用例 跟1.2.2.1是镜像关系 node = NULL; node = inserRB(node, 8, NULL); node = inserRB(node, 4, NULL); node = inserRB(node, 12, NULL); node = inserRB(node, 1, NULL); node = inserRB(node, 5, NULL); //特殊处理 node->left->color = 1; node->left->left->color = 0; node->left->right->color = 0; node = Delete(node, 12, node); printf("***1.2.2.1.4 测试用例 前序***: \n"); preOrderTraverse(node); //2 测试用例 node = NULL; node = inserRB(node, 8, NULL); node = inserRB(node, 4, NULL); node = inserRB(node, 12, NULL); node = inserRB(node, 3, NULL); node = Delete(node, 4, node); printf("***2 测试用例 前序***: \n"); preOrderTraverse(node); //3 测试用例 node = NULL; node = inserRB(node, 8, NULL); node = inserRB(node, 2, NULL); node = inserRB(node, 14, NULL); node = inserRB(node, 1, NULL); node = inserRB(node, 5, NULL); node = inserRB(node, 12, NULL); node = inserRB(node, 10, NULL); node = inserRB(node, 28, NULL); node = inserRB(node, 20, NULL); node = inserRB(node, 40, NULL); node = inserRB(node, 22, NULL); node = Delete(node, 20, node); printf("***3 测试用例 前序***: \n"); preOrderTraverse(node); }