Esempio n. 1
0
void rb_insert(rbtree* tree, int data) {
    rbnode* pn = rb_search(tree, data);
    rbnode* nn = create_rbnode(data);
    if (!pn) {
        tree->root = nn;
        nn->color = BLACK;
        return;
    }
    else if (data == pn->data) {
        return;
    }
    else if (data < pn->data) {
        pn->left = nn;
        nn->parent = pn;
    }
    else if (data > pn->data) {
        pn->right = nn;
        nn->parent = pn;
    }
    while (pn && pn->color == RED) {
        if (IS_LEFT(pn)) {
            rbnode* uncle = pn->parent->right;
            if (uncle && uncle->color == RED) {
                pn->color = uncle->color = BLACK;
                pn->parent->color = RED;
                nn = pn->parent;
                pn = nn->parent;
                continue;
            }
            if (IS_RIGHT(nn)) {
                LEFT_ROTATE(tree, pn);
                SWAP(nn, pn, rbnode*);
            }
            RIGHT_ROTATE(tree, pn->parent);
            pn->color = BLACK;
            pn->right->color = RED;
            break;
        }
        else {
            rbnode* uncle = pn->parent->left;
            if (uncle && uncle->color == RED) {
                pn->color = uncle->color = BLACK;
                pn->parent->color = RED;
                nn = pn->parent;
                pn = nn->parent;
                continue;
            }
            if (IS_LEFT(nn)) {
                RIGHT_ROTATE(tree, pn);
                SWAP(nn, pn, rbnode*);
            }
            LEFT_ROTATE(tree, pn->parent);
            pn->color = BLACK;
            pn->left->color = RED;
            break;
        }
    }
    // nn is root
    if (!pn) nn->color = BLACK;
}
Esempio n. 2
0
void rb_insert_fixup(Node* &T, Node *n)
{
	// 如果n的父亲是红色,则需要调整
	// 如果n的父亲是黑色,则不需要调整,因为n本身是红色
	while(IS_RED(PARENT(n))) {
		// 根据n的叔叔节点的颜色,来决定调整方案
		Node *p = IS_LEFT(PARENT(n))? RIGHT(PARENT(PARENT(n))): LEFT(PARENT(PARENT(n)));

		// 如果叔叔是红色,那很简单,把爷爷的黑色转移给父亲和叔叔,爷爷刷成红色
		// 这样,即满足了性质4,也没有破坏性质5及其他性质
		// 但是,爷爷可能破坏了红黑性质4,则从爷爷开始继续调整(向上递归了两层)
		if (IS_RED(p)) {
			// 父亲刷成黑色
			SET_BLACK(PARENT(n));
			// 叔叔刷成黑色
			SET_BLACK(p);
			// 爷爷刷成红色
			SET_RED(PARENT(PARENT(n)));

			// 从爷爷开始继续调整
			n = PARENT(PARENT(n));
			continue;
		} 

		// 如果叔叔是黑色,就复杂一点,引入旋转操作
		// 如果n是左孩子,那么需要一次右旋+颜色调整即可
		// 如果n是右孩子,则通过一次左旋调整成左孩子,然后按上面情况处理
		if (IS_LEFT(PARENT(n))) { 
			// 如果n是右孩子,通过右旋调整成左孩子
			if (IS_RIGHT(n)) {
				n = PARENT(n);
				left_rotate(T, n);
			}

			// 现在n是左孩子了
			SET_BLACK(PARENT(n));
			SET_RED(PARENT(PARENT(n)));
			right_rotate(T, PARENT(PARENT(n)));
		} else {
			if (IS_LEFT(n)) {
				n = PARENT(n);
				right_rotate(T,n);
			}
			SET_BLACK(PARENT(n));
			SET_RED(PARENT(PARENT(n)));
			left_rotate(T,PARENT(PARENT(n)));
		}
	}
	
	// 如果n是根节点,则把根设置为黑色
	if (NIL == PARENT(n))
		SET_BLACK(n);
}
Esempio n. 3
0
void right_rotate(Node* &T, Node *x)
{
	if (NIL == LEFT(x))
		return;

	Node *y = LEFT(x);

	// y的右孩子挂到x的左孩子
	LEFT(x) = RIGHT(y);
	if (NIL != RIGHT(y))
		PARENT(RIGHT(y)) = x;
	
	// x的父亲作为y的父亲
	PARENT(y) = PARENT(x);

	// x是根节点,则y是新的根;否则,把y挂到x的父节点下
	if (NIL == PARENT(x)) {
		T = y;
	} else if (IS_LEFT(x)) {
		LEFT(PARENT(x)) = y;
	} else {
		RIGHT(PARENT(x)) = y;
	}

	// 把x挂到y的右孩子
	RIGHT(y) = x;
	PARENT(x) = y;

	// 重新计算x和y的max值
	MAX(x) = max(MAX(LEFT(x)), MAX(RIGHT(x)), HIGH(KEY(x)));
	MAX(y) = max(MAX(LEFT(y)), MAX(RIGHT(y)), HIGH(KEY(y)));
}
Esempio n. 4
0
void right_rotate(Node* &T, Node *x)
{
	if (NIL == LEFT(x))
		return;

	Node *y = LEFT(x);

	// y的右孩子挂到x的左孩子
	LEFT(x) = RIGHT(y);
	if (NIL != RIGHT(y))
		PARENT(RIGHT(y)) = x;
	
	// x的父亲作为y的父亲
	PARENT(y) = PARENT(x);

	// x是根节点,则y是新的根;否则,把y挂到x的父节点下
	if (NIL == PARENT(x)) {
		T = y;
	} else if (IS_LEFT(x)) {
		LEFT(PARENT(x)) = y;
	} else {
		RIGHT(PARENT(x)) = y;
	}

	// 把x挂到y的右孩子
	RIGHT(y) = x;
	PARENT(x) = y;

	// 现在开始重新计算各个节点的size
	// 其实只有x和y的size发生变化
	// y的新size不需要计算,就是x的旧size
	// x的新size,则需要重新计算
	SIZE(y) = SIZE(x);
	SIZE(x) = SIZE(LEFT(x)) + SIZE(RIGHT(x)) + 1;
}
Esempio n. 5
0
Node* tree_predecessor(const Node *n)
{
	Node *p = const_cast<Node*>(n);
	if (NIL == p)
		return p;
	
	if (NIL != LEFT(p))
		return tree_max(LEFT(p));

	while(IS_LEFT(p) && (p = PARENT(p)));
	return PARENT(p);
}
Esempio n. 6
0
static void RIGHT_ROTATE(rbtree* tree, rbnode* n)
{
    int is_left = IS_LEFT(n);
    int is_right = IS_RIGHT(n);
    rbnode* l = n->left;
    l->parent = n->parent;
    if (is_left) l->parent->left = l;
    else if (is_right) l->parent->right = l;
    else tree->root = l;
    n->left = l->right;
    if (n->left) n->left->parent = n;
    l->right = n;
    n->parent = l;
}
Esempio n. 7
0
static void LEFT_ROTATE(rbtree* tree, rbnode* n)
{
    int is_left = IS_LEFT(n);
    int is_right = IS_RIGHT(n);
    rbnode* r = n->right;
    r->parent = n->parent;
    if (is_left) r->parent->left = r;
    else if (is_right) r->parent->right = r;
    else tree->root = r;
    n->right = r->left;
    if (n->right) n->right->parent = n;
    r->left = n;
    n->parent = r;
}
Esempio n. 8
0
void tree_delete(Node* &T, Node *x)
{
	if (NIL == T || NIL == x)
		return;

	// y是要删除的节点
	Node *y = NULL;
	if ((NIL == LEFT(x)) || (NIL == RIGHT(x))) 
		y = x;
	else 
		y = tree_successor(x);

	if (y != x)
		KEY(x) = KEY(y);

	// y肯定只有一个孩子
	Node * z = (NIL != LEFT(y))? LEFT(y): RIGHT(y);	
	// 即使z是NIL,也给挂上,否则会影响rb_delete_fixup
	PARENT(z) = PARENT(y);

	if (NIL == PARENT(y)) {
		// 根节点发生变化
		T = z;
	} else if (IS_LEFT(y)){
		LEFT(PARENT(y)) = z;
	} else {
		RIGHT(PARENT(y)) = z;
	}

	
	// 调整路径上节点的max值
	Node *p = PARENT(z);
	while (NIL != p) {
		MAX(p) = max(MAX(LEFT(p)), MAX(RIGHT(p)), HIGH(KEY(p)));
		p = PARENT(p);
	}

	// 如果y是黑色,说明破坏红黑树的规则;如果y是红色,则不会破坏
	if (IS_BLACK(y)) {
		rb_delete_fixup(T, z);
	}
	free_node(y);
}
Esempio n. 9
0
void tree_delete(Node* &T, Node *x)
{
	if (NIL == T || NIL == x)
		return;

	// y是要删除的节点
	Node *y = NULL;
	if ((NIL == LEFT(x)) || (NIL == RIGHT(x))) 
		y = x;
	else 
		y = tree_successor(x);

	if (y != x)
		KEY(x) = KEY(y);

	// y肯定只有一个孩子
	Node * z = (NIL != LEFT(y))? LEFT(y): RIGHT(y);	
	// 即使z是NIL,也给挂上,否则会影响rb_delete_fixup
	PARENT(z) = PARENT(y);

	if (NIL == PARENT(y)) {
		// 根节点发生变化
		T = z;
	} else if (IS_LEFT(y)){
		LEFT(PARENT(y)) = z;
	} else {
		RIGHT(PARENT(y)) = z;
	}

	// 沿着y节点向上,更新路径上每个节点的size
	Node *p = y;
	while (NIL != (p=PARENT(p))) {
		SIZE(p)--;
	}

	// 如果y是黑色,说明破坏红黑树的规则;如果y是红色,则不会破坏
	if (IS_BLACK(y)) {
		rb_delete_fixup(T, z);
	}
	free_node(y);
}
Esempio n. 10
0
static inline void node_rotate_left(map_t *map, mapnode_t *node)
{
    mapnode_t *right = node->right;
    node->right = right->left;
    if (node->right != NIL)
      node->right->parent = node;

    right->parent = node->parent;

    if (node->parent == NIL) {
      map->root = right;
    } else {
      if (IS_LEFT(node)) {
        node->parent->left = right;
      } else {
        node->parent->right = right;
      }
    }

    right->left = node;
    node->parent = right;
}
Esempio n. 11
0
void map_insert(map_t *map, mapkey_t key, void *p)
{
  allocator_t *alloc = map->allocator;
  mapnode_t *parent = map->root;
  mapnode_t **slot = &map->root;
  mapnode_t *insert;

  while (parent != NIL) {
    int comparison = map->ops.compare_key(key, parent->key);
    if (comparison == 0) {
      map->ops.destroy_value(parent->p, alloc);
      parent->p = map->ops.copy_value(p, alloc);
      return;
    } else if (comparison < 0) {
      if (parent->left != NIL) {
        parent = parent->left;
        continue;
      } else {
        slot = &parent->left;
        break;
      }
    } else {
      if (parent->right != NIL) {
        parent = parent->right;
        continue;
      } else {
        slot = &parent->right;
        break;
      }
    }
  }

  map->size += 1;
  insert = (mapnode_t *)com_malloc(map->allocator, sizeof(mapnode_t));
  insert->left = insert->right = NIL;
  insert->key = map->ops.copy_key(key, alloc);
  insert->p = map->ops.copy_value(p, alloc);
  insert->color = RED;
  insert->parent = parent;

  *slot = insert;

  while (IS_RED(insert->parent) && node_grandparent(insert) != NIL) {
    mapnode_t *uncle = node_sibling(insert->parent);
    if (IS_RED(uncle)) {
      insert->parent->color = BLACK;
      uncle->color = BLACK;
      uncle->parent->color = RED;
      insert = uncle->parent;
    } else {
      int insleft = IS_LEFT(insert);
      int parleft = IS_LEFT(insert->parent);

      if (!insleft && parleft) {
        insert = insert->parent;
        node_rotate_left(map, insert);
      } else if (insleft && !parleft) {
        insert = insert->parent;
        node_rotate_right(map, insert);
      }

      insert->parent->parent->color = RED;
      insert->parent->color = BLACK;

      if (parleft)
        node_rotate_right(map, insert->parent->parent);
      else
        node_rotate_left(map, insert->parent->parent);
    }
  }

  map->root->color = BLACK;

#if !defined(NDEBUG)
  map_test(map->root);
#endif
}
Esempio n. 12
0
static inline mapnode_t *node_sibling(mapnode_t *node)
{
  if (node->parent == NIL) return NIL;

  return IS_LEFT(node) ? node->parent->right : node->parent->left;
}
Esempio n. 13
0
void rb_delete(rbtree* tree, int data) {
    int color = RED;
    rbnode* dn = tree->root;
    rbnode* x = 0;
    rbnode* y = 0; //parent of deleted node
    rbnode* s = 0; //sibling
    rbnode* p = 0; //parent
    rbnode* ln =0; //left nephew
    rbnode* rn = 0; //right nephew
    int delcolor = 0;

    while (dn) {
        if (dn->data == data) break;
        else if (data < dn->data) dn = dn->left;
        else dn = dn->right;
    }
    if (!dn) return;

    delcolor = dn->color;
    y = dn->parent;
    if (!dn->left && !dn->right) {
        REPLACE(tree, dn, ((rbnode*)0));
        x = 0;
    }
    else if (!dn->left) {
        REPLACE(tree, dn, dn->right);
        x = dn->right;
    }
    else if (!dn->right) {
        REPLACE(tree, dn, dn->left);
        x = dn->left;
    }
    else {
        rbnode* rl = dn->right;
        while (rl->left) rl = rl->left;
        x = rl->right;
        y = rl == dn->right ? rl : rl->parent;
        delcolor = rl->color;
        REPLACE(tree, rl, rl->right);
        REPLACE(tree, dn, rl);
        rl->left = dn->left;
        rl->right = dn->right;
        rl->color = dn->color;
    }
    if (delcolor == RED) {
        destory_rbnode(dn);
        return;
    }
    while (IS_BLACK(x) && x != tree->root) {
        p = x ? x->parent : y;
        if ((!x && !y->left) || IS_LEFT(x)) {
            s = p->right;//s != 0,because x is black, the path to from s to null must has at least a black node

            if (s->color == RED) {
                LEFT_ROTATE(tree,p);
                p->color = RED;
                s->color = BLACK;
                continue;
            }
            else if (IS_BLACK(s->left) && IS_BLACK(s->right)) {
                s->color = RED;
                x = p;
                continue; 
            }
            ln = s->left;
            rn = s->right;

            if (IS_BLACK(rn)) {
                RIGHT_ROTATE(tree,s);
                s->color = RED;
                ln->color = BLACK;
                continue;
            }
            else {
                LEFT_ROTATE(tree,p);
                s->color = p->color;
                p->color = BLACK;
                x = rn;
                break;
            }
        }
        else if ((!x && !y->right) || IS_RIGHT(x)) {
            s = p->left;//s != 0,because x is black, the path to from s to null must has at least a black node

            if (s->color == RED) {
                RIGHT_ROTATE(tree,p);
                p->color = RED;
                s->color = BLACK;
                continue;
            }
            else if (IS_BLACK(s->left) && IS_BLACK(s->left)) {
                s->color = RED;
                x = p;
                continue; 
            }
            ln = s->left;
            rn = s->left;

            if (IS_BLACK(ln)) {
                LEFT_ROTATE(tree,s);
                s->color = RED;
                rn->color = BLACK;
                continue;
            }
            else {
                RIGHT_ROTATE(tree,p);
                s->color = p->color;
                p->color = BLACK;
                x = ln;
                break;
            }
        }
    }
    if (x) x->color = BLACK;
    destory_rbnode(dn);
    return;
}
Esempio n. 14
0
void rb_delete_fixup(Node* &T, Node *x)
{
	while ((NIL!= x) && !IS_ROOT(x) && IS_BLACK(x)) {
		if (IS_LEFT(x)) {
			// w是x的右兄弟,w是下面不同处理方式的选择依据
			// 总共四种处理方式:
			// case 1: w是红色,两个孩子的颜色无所谓
			// case 2: w是黑色,左孩子黑色,右孩子黑色
			// case 3: w是黑色,左孩子红色,右孩子黑色
			// case 4: w是黑色,右孩子红色,左孩子的颜色无所谓
			Node *w = RIGHT(PARENT(x));  
			// case1: w是红色,则通过一次左旋,并刷成黑色,转成case 2、3、4
			if (IS_RED(w)) {
				SET_BLACK(w);
				SET_RED(PARENT(x));
				left_rotate(T, PARENT(x));
			}
			
			// case 2: w的两个孩子都是黑色,把w刷成红色,x的父亲取代x,向上递归处理
			if (IS_BLACK(LEFT(w)) && IS_BLACK(RIGHT(w))) {
				SET_RED(w);
				x = PARENT(x);
				continue;
			}
			// case 3: w的左孩子红色,右孩子黑色,把w左孩子刷成黑色,w刷成红色,做一次右旋,转成case 4
			if (IS_BLACK(RIGHT(w))) {
				SET_BLACK(LEFT(w));
				SET_RED(w);
				right_rotate(T, w);
				w = PARENT(w);    // 转成case 4
			} 
			
			// case 4: w的右孩子为红色,把w刷成红色,w右节点刷成黑色,x父亲刷成黑色,做一次左旋,满足红黑性质,结束处理
			COLOR(w) = COLOR(PARENT(x));
			SET_BLACK(RIGHT(w));
			SET_BLACK(PARENT(x));
			left_rotate(T, PARENT(x));
			x = T; 
		} else {
			// w是x的左兄弟,w是下面不同处理方式的选择依据
			// 总共四种处理方式:
			// case 1: w是红色,两个孩子的颜色无所谓
			// case 2: w是黑色,左孩子黑色,右孩子黑色
			// case 3: w是黑色,左孩子红色,右孩子黑色
			// case 4: w是黑色,右孩子红色,左孩子的颜色无所谓
			Node *w = LEFT(PARENT(x));  
			// case1: w是红色,则通过一次右旋,并刷成黑色,转成case 2、3、4
			if (IS_RED(w)) {
				SET_BLACK(w);
				SET_RED(PARENT(x));
				right_rotate(T, PARENT(x));
			}
			
			// case 2: w的两个孩子都是黑色,把w刷成红色,x的父亲取代x,线上递归处理
			if (IS_BLACK(LEFT(w)) && IS_BLACK(RIGHT(w))) {
				SET_RED(w);
				x = PARENT(x);
				continue;
			}
			// case 3: w的左孩子黑色,右孩子红色,把w右孩子刷成黑色,w刷成红色,做一次左旋,转成case 4
			if (IS_BLACK(LEFT(w))) {
				SET_BLACK(RIGHT(w));
				SET_RED(w);
				left_rotate(T, w);
				w = PARENT(w);    // 转成case 4
			}
			
			// case 4: w的左孩子为红色,把w刷成红色,w左节点刷成黑色,x父亲刷成黑色,做一次右旋,满足红黑性质,结束处理
			COLOR(w) = COLOR(PARENT(x));
			SET_BLACK(LEFT(w));
			SET_BLACK(PARENT(x));
			right_rotate(T, PARENT(x));
			x = T;
		}
	}

	// 如果x是根节点,或为红色,则都刷成黑色,即可保持红黑树性质
	SET_BLACK(x);
}