Example #1
0
extern int
ct_bintree_remove(node_t **rootaddr, PyObject *key)
{
	node_t *node, *parent, *replacement;
	int direction, cmp_res, down_dir;

	node = *rootaddr;

	if (node == NULL)
		return 0; 
	parent = NULL;
	direction = 0;

	while (1) {
		cmp_res = ct_compare(key, KEY(node));
		if (cmp_res == 0) 
		{
			if ((LEFT_NODE(node) != NULL) && (RIGHT_NODE(node) != NULL)) {
				
				parent = node;
				direction = RIGHT;
				replacement = RIGHT_NODE(node);
				while (LEFT_NODE(replacement) != NULL) {
					parent = replacement;
					direction = LEFT;
					replacement = LEFT_NODE(replacement);
				}
				LINK(parent, direction) = RIGHT_NODE(replacement);
				
				ct_swap_data(node, replacement);
				node = replacement; 
			}
			else {
				down_dir = (LEFT_NODE(node) == NULL) ? RIGHT : LEFT;
				if (parent == NULL) 
				{
					*rootaddr = LINK(node, down_dir);
				}
				else {
					LINK(parent, direction) = LINK(node, down_dir);
				}
			}
			ct_delete_node(node);
			return 1; 
		}
		else {
			direction = (cmp_res < 0) ? LEFT : RIGHT;
			parent = node;
			node = LINK(node, direction);
			if (node == NULL)
				return 0; 
		}
	}
}
Example #2
0
void
ct_bintree_remove(node_t **rootaddr, node_t *node)
{
	node_t **pnode = NULL; 
	node_t *tmp;

	if (*rootaddr == node) {
		// the node is the root
		pnode = rootaddr;
	} else {
		node_t *parent = PARENT_NODE(node); 
		if (LEFT_NODE(parent) == node) {
			pnode = &LEFT_NODE(parent); 
		} else {
			pnode = &RIGHT_NODE(parent); 
		}
	}

	if (LEFT_NODE(node) == NULL) {
		// replace the root with the right sub-tree
		tmp = *pnode = RIGHT_NODE(node);
		if (tmp != NULL) {
			PARENT_NODE(tmp) = PARENT_NODE(node);
		}
		ct_delete_node(node);
	} else if (RIGHT_NODE(node) == NULL) {
		// replace the node with the left sub-tree
		tmp = *pnode = LEFT_NODE(node);
		PARENT_NODE(tmp) = PARENT_NODE(node);
		ct_delete_node(node);
	} else {
		// both left and right sub-tree is non-null, replace by smallest key in right sub-tree
		node_t **pleftmost = &RIGHT_NODE(node);
		node_t *leftmost = RIGHT_NODE(node); // assert leftmost != NULL
		while ((tmp = LEFT_NODE(leftmost)) != NULL) {
			pleftmost = &LEFT_NODE(leftmost);
			leftmost = tmp;
		}
		// found the leftmost node, copy its data to the root, then remove the left most node
		ct_swap_data(node, leftmost);

		tmp = *pleftmost = RIGHT_NODE(leftmost);
		if (tmp != NULL) {
			PARENT_NODE(tmp) = PARENT_NODE(leftmost);
		}
		ct_delete_node(leftmost);
	}
}
Example #3
0
extern int
rb_remove(node_t **rootaddr, node_t *_node)
{
	PyObject *key = KEY(_node);
	node_t *root = *rootaddr;

	node_t head = { { NULL } }; /* False tree root */
	node_t *q, *p, *g; /* Helpers */
	node_t *f = NULL; /* Found item */
	node_t *tmp;
	int dir = 1;

	if (root == NULL)
		return 0;

	/* Set up our helpers */
	q = &head;
	g = p = NULL;
	RIGHT_NODE(q) = root;

	/*
	 Search and push a red node down
	 to fix red violations as we go
	 */
	while (q->link[dir] != NULL) {
		int last = dir;
		int cmp_res;

		/* Move the helpers down */
		g = p, p = q;
		q = q->link[dir];

		cmp_res =  ct_compare(KEY(q), key);

		dir = cmp_res < 0;

		/*
		 Save the node with matching data and keep
		 going; we'll do removal tasks at the end
		 */
		if (cmp_res == 0)
			f = q;

		/* Push the red node down with rotations and color flips */
		if (!is_red(q) && !is_red(q->link[dir])) {
			if (is_red(q->link[!dir])) {
				tmp = rb_single(q, dir);
				PARENT_NODE(tmp) = p;
				p = p->link[last] = tmp;
			}
			else if (!is_red(q->link[!dir])) {
				node_t *s = p->link[!last];

				if (s != NULL) {
					if (!is_red(s->link[!last]) &&
						!is_red(s->link[last])) {
						/* Color flip */
						RED(p) = 0;
						RED(s) = 1;
						RED(q) = 1;
					}
					else {
						int dir2 = g->link[1] == p;

						if (is_red(s->link[last])) {
							tmp = g->link[dir2] = rb_double(p, last);
							PARENT_NODE(tmp) = g;
						}
						else if (is_red(s->link[!last])) {
							tmp = g->link[dir2] = rb_single(p, last);
							PARENT_NODE(tmp) = g;
						}

						/* Ensure correct coloring */
						RED(q) = RED(g->link[dir2]) = 1;
						RED(g->link[dir2]->link[0]) = 0;
						RED(g->link[dir2]->link[1]) = 0;
					}
				}
			}
		}
	}

	/* Replace and remove the saved node */
	if (f != NULL) {
		ct_swap_data(f, q);
		p->link[p->link[1] == q] = q->link[q->link[0] == NULL];
		ct_delete_node(q);
	}

	/* Update the root (it may be different) */
	root = head.link[1];

	/* Make the root black for simplified logic */
	if (root != NULL) {
		RED(root) = 0;
		PARENT_NODE(root) = NULL;
	}
	*rootaddr = root;
	return (f != NULL);
}
Example #4
0
extern int
avl_remove(node_t **rootaddr, PyObject *key)
{
	node_t *root = *rootaddr;
	int cmp_res;

	if (root != NULL) {
		node_t *it, *up[32];
		int upd[32], top = 0;

		it = root;
		for (;;) {
			
			if (it == NULL)
				return 0;
			cmp_res = ct_compare(KEY(it), key);
			if (cmp_res == 0)
				break;

			
			upd[top] = (cmp_res < 0);
			up[top++] = it;
			it = it->link[upd[top - 1]];
		}

		
		if (it->link[0] == NULL ||
			it->link[1] == NULL) {
			
			int dir = it->link[0] == NULL;

			
			if (top != 0)
				up[top - 1]->link[upd[top - 1]] = it->link[dir];
			else
				root = it->link[dir];

			ct_delete_node(it);
		}
		else {
			
			node_t *heir = it->link[1];

			
			upd[top] = 1;
			up[top++] = it;

			while ( heir->link[0] != NULL ) {
				upd[top] = 0;
				up[top++] = heir;
				heir = heir->link[0];
			}
			
			ct_swap_data(it, heir);
			
			up[top - 1]->link[up[top - 1] == it] = heir->link[1];
			ct_delete_node(heir);
		}

		
		while (--top >= 0) {
			int lh = height(up[top]->link[upd[top]]);
			int rh = height(up[top]->link[!upd[top]]);
			int max = avl_max(lh, rh);

			
			BALANCE(up[top]) = max + 1;

			
			if (lh - rh == -1)
				break;
			if (lh - rh <= -2) {
				node_t *a = up[top]->link[!upd[top]]->link[upd[top]];
				node_t *b = up[top]->link[!upd[top]]->link[!upd[top]];

				if (height(a) <= height(b))
					up[top] = avl_single(up[top], upd[top]);
				else
					up[top] = avl_double(up[top], upd[top]);

				
				if (top != 0)
					up[top - 1]->link[upd[top - 1]] = up[top];
				else
					root = up[0];
			}
		}
	}
	(*rootaddr) = root;
	return 1;
}
Example #5
0
extern int
rb_remove(node_t **rootaddr, PyObject *key)
{
	node_t *root = *rootaddr;

	node_t head = { { NULL } }; 
	node_t *q, *p, *g; 
	node_t *f = NULL; 
	int dir = 1;

	if (root == NULL)
		return 0;

	
	q = &head;
	g = p = NULL;
	RIGHT_NODE(q) = root;

	while (q->link[dir] != NULL) {
		int last = dir;
		int cmp_res;

		
		g = p, p = q;
		q = q->link[dir];

		cmp_res =  ct_compare(KEY(q), key);

		dir = cmp_res < 0;

		if (cmp_res == 0)
			f = q;

		
		if (!is_red(q) && !is_red(q->link[dir])) {
			if (is_red(q->link[!dir]))
				p = p->link[last] = rb_single(q, dir);
			else if (!is_red(q->link[!dir])) {
				node_t *s = p->link[!last];

				if (s != NULL) {
					if (!is_red(s->link[!last]) &&
						!is_red(s->link[last])) {
						
						RED(p) = 0;
						RED(s) = 1;
						RED(q) = 1;
					}
					else {
						int dir2 = g->link[1] == p;

						if (is_red(s->link[last]))
							g->link[dir2] = rb_double(p, last);
						else if (is_red(s->link[!last]))
							g->link[dir2] = rb_single(p, last);

						
						RED(q) = RED(g->link[dir2]) = 1;
						RED(g->link[dir2]->link[0]) = 0;
						RED(g->link[dir2]->link[1]) = 0;
					}
				}
			}
		}
	}

	
	if (f != NULL) {
		ct_swap_data(f, q);
		p->link[p->link[1] == q] = q->link[q->link[0] == NULL];
		ct_delete_node(q);
	}

	
	root = head.link[1];

	
	if (root != NULL)
		RED(root) = 0;
	*rootaddr = root;
	return (f != NULL);
}