/****************************************************************************** **函数名称: rbt_right_rotate **功 能: 右旋处理 **输入参数: ** tree: 红黑树 ** node: 旋转支点 **输出参数: NONE **返 回: RBT_OK:成功 RBT_ERR:失败 **实现描述: ** G G ** | | ** N -> L ** / \ / \ ** L R LL N ** / \ / \ / \ ** LL LR RL RR LR R ** / \ ** RL RR ** 说明: 节点N为旋转支点 **注意事项: **作 者: # Qifeng.zou # 2014.01.15 # ******************************************************************************/ static void rbt_right_rotate(rbt_tree_t *tree, rbt_node_t *node) { rbt_node_t *parent = node->parent, *lchild = node->lchild; if (tree->sentinel == parent) { tree->root = lchild; lchild->parent = tree->sentinel; } else if (node == parent->lchild) { rbt_set_lchild(tree, parent, lchild); } else { rbt_set_rchild(tree, parent, lchild); } rbt_set_lchild(tree, node, lchild->rchild); rbt_set_rchild(tree, lchild, node); rbt_assert(tree, node); rbt_assert(tree, lchild); rbt_assert(tree, parent); }
int main(){ Rbt_tree_link a = rbt_create(); Rbtlink it; srand(time(NULL)); puts("Inserting..."); for(i=0;i<N;i++) { num[i] = rand() % N; rbt_insert(a,num[i]); } printf("rbt_size: %d\n",rbt_size(a)); printf("min value:%d max value:%d\n",rbt_item(rbt_minimum(a)),rbt_item(rbt_maximum(a))); puts("Doing assert..."); rbt_assert(a); puts("Traversing (inorder)..."); rbt_inorder(a,func); for(i=0; i < N; i++) rbt_search(a, i); puts("Traversing (from max to min)..."); it = rbt_maximum(a); for(i = rbt_size(a)-1; i >= 0; i--) { assert(n[i] == rbt_item(it)); it = rbt_predecessor(it); } printf("rbt_size: %d\n",rbt_size(a)); puts("Deleting all values..."); int i = 0; for (i = 0; i < N; ++i) { printf("%d deleted\r", num[i]); rbt_delete(a, num[i]); } puts("\nDestroying rbt.."); rbt_destroy(a); puts("OK!"); return 0; }
/****************************************************************************** **函数名称: rbt_print **功 能: 打印红黑树(外部接口) **输入参数: ** tree: 红黑树 **输出参数: NONE **返 回: VOID **实现描述: **注意事项: **作 者: # Qifeng.zou # 2013.12.17 # ******************************************************************************/ int rbt_print(rbt_tree_t *tree) { int depth = 0; Stack_t _stack, *stack = &_stack; rbt_node_t *node = tree->root, *parent = NULL; if (tree->sentinel == node) return 0; stack_init(stack, RBT_MAX_DEPTH); while (tree->sentinel != node) { /* 压左孩子入栈 */ while (tree->sentinel != node->lchild) { rbt_assert(tree, node); depth = stack_depth(stack); stack_push(stack, node); rbt_print_head(tree, node, depth); /* 打印头:入栈时打印头 出栈时打印尾 */ node = node->lchild; } /* 打印最左端的子孙结点 */ depth = stack_depth(stack); rbt_print_head(tree, node, depth); /* 最左端的孩子有右孩子 */ if (tree->sentinel != node->rchild) { stack_push(stack, node); node = node->rchild; continue; } /* 最左端的孩子无右孩子 */ rbt_print_tail(tree, node, depth); parent = stack_gettop(stack); if (NULL == parent) { return stack_destroy(stack); } /* 判断最左结点的父结点未处理完成 */ if (parent->lchild == node) { if (tree->sentinel != parent->rchild) { node = parent->rchild; continue; } } /* 判断最左结点的父结点已处理完成 */ while ((node == parent->rchild) || (tree->sentinel == parent->rchild)) { stack_pop(stack); depth = stack_depth(stack); rbt_print_tail(tree, parent, depth); /* 打印尾:出栈时打印尾 入栈时已打印头 */ node = parent; parent = stack_gettop(stack); if (NULL == parent) { return stack_destroy(stack); } } node = parent->rchild; } return stack_destroy(stack); }
/****************************************************************************** **函数名称: rbt_delete_fixup **功 能: 修复删除操作造成的黑红树性质的破坏(内部接口) **输入参数: ** tree: 红黑树 ** node: 实际被删结点的替代结点(注: node有可能是叶子结点) **输出参数: NONE **返 回: RBT_OK:成功 RBT_ERR:失败 **实现描述: **注意事项: 被删结点为黑色结点,才能调用此函数进行性质调整 **作 者: # Qifeng.zou # 2013.12.28 # ******************************************************************************/ static int rbt_delete_fixup(rbt_tree_t *tree, rbt_node_t *node) { rbt_node_t *parent = NULL, *brother = NULL; while (rbt_is_black(node) && (tree->root != node)) { /* Set parent and brother */ parent = node->parent; if (node == parent->lchild) { brother = parent->rchild; /* Case 1: 兄弟结点为红色: 以parent为支点, 左旋处理 */ if (rbt_is_red(brother)) { rbt_set_red(parent); rbt_set_black(brother); rbt_left_rotate(tree, parent); /* 参照结点node不变, 兄弟结点改为parent->rchild */ brother = parent->rchild; /* 注意: 此时处理还没有结束,还需要做后续的调整处理 */ } /* Case 2: 兄弟结点为黑色(默认), 且兄弟结点的2个子结点都为黑色 */ if (rbt_is_black(brother->lchild) && rbt_is_black(brother->rchild)) { rbt_set_red(brother); node = parent; } else { /* Case 3: 兄弟结点为黑色(默认), 兄弟节点的左子结点为红色, 右子结点为黑色: 以brother为支点, 右旋处理 */ if (rbt_is_black(brother->rchild)) { rbt_set_black(brother->lchild); rbt_set_red(brother); rbt_right_rotate(tree, brother); /* 参照结点node不变 */ brother = parent->rchild; } /* Case 4: 兄弟结点为黑色(默认), 兄弟结点右孩子结点为红色: 以parent为支点, 左旋处理 */ rbt_copy_color(brother, parent); rbt_set_black(brother->rchild); rbt_set_black(parent); rbt_left_rotate(tree, parent); node = tree->root; } } else { brother = parent->lchild; /* Case 5: 兄弟结点为红色: 以parent为支点, 右旋处理 */ if (rbt_is_red(brother)) { rbt_set_red(parent); rbt_set_black(brother); rbt_right_rotate(tree, parent); /* 参照结点node不变 */ brother = parent->lchild; /* 注意: 此时处理还没有结束,还需要做后续的调整处理 */ } /* Case 6: 兄弟结点为黑色(默认), 且兄弟结点的2个子结点都为黑色 */ if (rbt_is_black(brother->lchild) && rbt_is_black(brother->rchild)) { rbt_set_red(brother); node = parent; } else { /* Case 7: 兄弟结点为黑色(默认), 兄弟节点的右子结点为红色, 左子结点为黑色: 以brother为支点, 左旋处理 */ if (rbt_is_black(brother->lchild)) { rbt_set_red(brother); rbt_set_black(brother->rchild); rbt_left_rotate(tree, brother); /* 参照结点node不变 */ brother = parent->lchild; } /* Case 8: 兄弟结点为黑色(默认), 兄弟结点左孩子结点为红色: 以parent为支点, 右旋处理 */ rbt_copy_color(brother, parent); rbt_set_black(brother->lchild); rbt_set_black(parent); rbt_right_rotate(tree, parent); node = tree->root; } } } rbt_set_black(node); rbt_assert(tree, node); rbt_assert(tree, brother); rbt_assert(tree, parent); return RBT_OK; }
/****************************************************************************** **函数名称: rbt_trav **功 能: 遍历红黑树(外部接口) **输入参数: ** tree: 红黑树 ** cb: 回调函数 ** args: 附加参数 **输出参数: NONE **返 回: VOID **实现描述: 处理思路可以参考rbt_print(), 但是稍微有些不同之处. **注意事项: **作 者: # Qifeng.zou # 2014.12.26 # ******************************************************************************/ int rbt_trav(rbt_tree_t *tree, trav_cb_t proc, void *args) { Stack_t _stack, *stack = &_stack; rbt_node_t *node = tree->root, *parent; if (tree->sentinel == node) { return 0; } stack_init(stack, RBT_MAX_DEPTH); while (tree->sentinel != node) { /* 压左孩子入栈, 直到最左端 */ while (tree->sentinel != node->lchild) { rbt_assert(tree, node); stack_push(stack, node); node = node->lchild; } proc(node->data, args); /* 处理最左端结点 */ /* 最左端结点有右孩子 */ if (tree->sentinel != node->rchild) { stack_push(stack, node); /* 最左端结点入栈 */ node = node->rchild; continue; } /* 最左端结点无右孩子 */ parent = stack_gettop(stack); if (NULL == parent) { return stack_destroy(stack); } if (parent->lchild == node) { proc(parent->data, args); /* 处理最左结点的父结点 */ if (tree->sentinel != parent->rchild) { /* 有右子树 */ node = parent->rchild; /* 处理右子树 */ continue; } else { stack_pop(stack); node = parent; parent = stack_gettop(stack); if (NULL == parent) { return stack_destroy(stack); } } } /* 判断最左结点的父结点已处理完成 */ while ((node == parent->rchild) || (tree->sentinel == parent->rchild)) { stack_pop(stack); node = parent; parent = stack_gettop(stack); if (NULL == parent) { return stack_destroy(stack); } } proc(parent->data, args); /* 处理有左子树而无右子树的结点 */ node = parent->rchild; } return stack_destroy(stack); }