可以不使用parent 指针,直接使用栈实现,方法是在插入时记下插入结点的所有祖先结点,然后回溯时再使用,以下代码使用数组简单实现栈结构。
/* ================================================================== */
/* no parent rbtree */
/* ================================================================== */
void __rb_np_rotate_left(struct rb_node *node, struct rb_node *parent, struct rb_root *root)
{
struct rb_node *right = node->right;
node->right = right->left;
right->left = node;
if (parent == NULL) {
root->rb_node = right;
}
else {
if (parent->left == node)
parent->left = right;
else
parent->right = right;
}
}
void __rb_np_rotate_right(struct rb_node *node, struct rb_node *parent, struct rb_root *root)
{
struct rb_node *left = node->left;
node->left = left->right;
left->right = node;
if (parent == NULL) {
root->rb_node = left;
}
else {
if (parent->left == node)
parent->left = left;
else
parent->right = left;
}
}
/* use s[0] as NULL pointer */
#define PUSH_S(s, n, i) (s)[++(i)]=(n)
#define POP_S(s, i) (s)[(i)--]
#define TOP_S(s, i) (s)[(i)]
static void rb_np_insert_color(struct rb_node *node, struct rb_root *root, struct rb_node **s, int i)
{
struct rb_node *parent, *uncle, *gparent, *tmp;
for (;;) {
parent = POP_S(s, i);
if (parent == NULL || parent->color == RB_BLACK) {
break;
}
gparent = POP_S(s, i);
if (parent == gparent->left) {
uncle = gparent->right;
if (uncle && uncle->color == RB_RED) { /* case 1 */
parent->color = RB_BLACK;
uncle->color = RB_BLACK;
gparent->color = RB_RED;
node = gparent;
continue;
}
if (parent->right == node) { /* case 2 */
__rb_np_rotate_left(parent, gparent, root);
tmp = node;
node = parent;
parent = tmp;
}
/* case 3 */
tmp = TOP_S(s, i);
__rb_np_rotate_right(gparent, tmp, root);
parent->color = RB_BLACK;
gparent->color = RB_RED;
break;
}
else {
uncle = gparent->left;
if (uncle && uncle->color == RB_RED) { /* case 1 */
parent->color = RB_BLACK;
uncle->color = RB_BLACK;
gparent->color = RB_RED;
node = gparent;
continue;
}
if (parent->left == node) { /* case 2 */
__rb_np_rotate_right(parent, gparent, root);
tmp = node;
node = parent;
parent = tmp;
}
/* case 3 */
tmp = TOP_S(s, i);
__rb_np_rotate_left(gparent, tmp, root);
parent->color = RB_BLACK;
gparent->color = RB_RED;
break;
}
}
root->rb_node->color = RB_BLACK;
}
void rb_np_insert(struct rb_node *node, struct rb_root *root)
{
int i = 0;
struct rb_node *p = root->rb_node, *parent = NULL;
struct rb_node *s[1024] = {0, };
while (p) {
PUSH_S(s, p, i);
if (node->key < p->key)
p = p->left;
else
p = p->right;
}
node->left = node->right = NULL;
parent = TOP_S(s, i);
if (parent == NULL) {
node->color = RB_BLACK;
root->rb_node = node;
}
else {
node->color = RB_RED;
if (node->key < parent->key)
parent->left = node;
else
parent->right = node;
if (parent->color == RB_RED)
rb_np_insert_color(node, root, s, i);
}
}