c语言红黑树,数据结构与算法 :红黑树 C语言实现

花了好几天的业余时间,看文章,总算是用C实现了一遍红黑树,主要还是自己C语言水平不够高,调试断点浪费了不少时间,闲话少说

·····································LSP的分割线·····································

最近整理代码,在掘金整理了最新的红黑树实现代码,比这里更整洁,这里就不重新发了,详见同名掘金博客

1. 红黑树结构体//这里偷懒就应0代表黑色,1代表红色了

typedef struct RBTreeNode {

int data; //数据域

int color; //0黑色 1红色

struct RBTreeNode *parent;//父亲结点

struct RBTreeNode *left; //左子结点

struct RBTreeNode *right; //右子结点

} RBTreeNode;

2. 前序遍历//这里打印了节点的颜色和父节点

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);

}

}

3.1 左旋

跟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;

}

3.2 右旋/**

* 右旋

* 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;

}

3.3 代码图解/**

* 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)

*

*

*/

4. 自平衡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;

}

5.1 插入(未平衡)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;

}

5.2 插入(平衡)RBTreeNode *inserRB(RBTreeNode *root, int data, RBTreeNode *parent)

{

root = insert(root,data,parent);

return rebalance3(RBTreeEndNode,root);

}

6 测试红黑树构建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);

}

测试结果:

bVcKNwB

7 红黑树删除图解*删除

*

*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了 递归

*

*

* (此处例外,不是删除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的情况

*/

8 红黑树删除代码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);

}

结果

bVcK0Ax

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值