예제 #1
0
void rbtree_node::remove(rbtree_node** root)
{
	rbtree_node* node = this;
	rbtree_node* child;
	rbtree_node* parent;
	int color;

	//
	// Satisfy Precondition: node has at most one non-null child
	//
	if (!node->left) {
		child = node->right;

	} else if (!node->right) {
		child = node->left;

	} else {
		rbtree_node* old = node;

		//
		// Locate a node that satisfies the precondition to swap with the node to be removed
		//
		node = node->right;
		while (node->left)
			node = node->left;

		//
		// Node satisfies precondition
		//
		child = node->right;

		//
		// Swap nodes (swap <-> (node <-> child))
		//
		parent = node->parent();
		color = node->color();

		if (child)
			child->parent(parent);

		if (parent == old) {
			parent->right = child;
			parent = node;
		} else {
			parent->left = child;
		}

		node->_parent = old->_parent;
		node->left = old->left;
		node->right = old->right;

		if (old->parent()) {
			UL_ASSERT((old->parent()->right == old) || (old->parent()->left == old));

			if (old->parent()->left == old) {
				old->parent()->left = node;

			} else {
				old->parent()->right = node;
			}

		} else {
			*root = node;
		}

		old->left->parent(node);
		if (old->right)
			old->right->parent(node);

		goto rm_color;
	}

	//
	// Replace Node with Child
	//
	parent = node->parent();
	color = node->color();
	if (child) {
		child->parent(parent);
	}
	if (parent) {
		UL_ASSERT((parent->right == node) || (parent->left == node));

		if (parent->left == node) {
			parent->left = child;

		} else {
			parent->right = child;
		}

	} else {
		*root = child;
	}

rm_color:
	//
	// Adjust Red-Black tree properties if node is black
	//
	if (color == black) {
		remove_color(child, parent, root);
	}

	UL_ASSERT(!*root || (*root)->color() == black);

	//
	// Bug prevention
	//
	this->_parent = 0;
	this->left = nullptr;
	this->right = nullptr;
}
예제 #2
0
static void remove_color(ul::rbtree_node* node, ul::rbtree_node* parent, ul::rbtree_node** root)
{
	ul::rbtree_node* sibling;

	//
	// Case 1
	//
	if (node && node->color() == ul::rbtree_node::red) {
		node->color(ul::rbtree_node::black);

	//
	// Cases: 2, 3, 4, 5, 6
	//
	// To reduce a number of repeated comparisions for the sibling, the code was duplicated and,
	// as a result, dead code paths were removed.
	//
	} else while (parent) {
		UL_ASSERT((node == parent->left) || (node == parent->right));
		if (node == parent->left) {
			sibling = parent->right;

			if (sibling->color() == ul::rbtree_node::red) {
				parent->color(ul::rbtree_node::red);
				sibling->color(ul::rbtree_node::black);
				rotate_left(parent, root);
				sibling = parent->right;
			}

			if (sibling->color() == ul::rbtree_node::black) {
				if (!sibling->right || sibling->right->color() == ul::rbtree_node::black) {
					if (!sibling->left || sibling->left->color() == ul::rbtree_node::black) {

						if (parent->color() == ul::rbtree_node::black) {
							sibling->color(ul::rbtree_node::red);
							node = parent;
							parent = node->parent();
							continue;

						} else {
							sibling->color(ul::rbtree_node::red);
							parent->color(ul::rbtree_node::black);
							break;
						}

					} else {
						sibling->color(ul::rbtree_node::red);
						sibling->left->color(ul::rbtree_node::black);
						rotate_right(sibling, root);
						sibling = parent->right;
					}
				}
				sibling->color(parent->color());
				parent->color(ul::rbtree_node::black);
				if (sibling->right)
					sibling->right->color(ul::rbtree_node::black);
				rotate_left(parent, root);
			}

		} else {
			sibling = parent->left;

			if (sibling->color() == ul::rbtree_node::red) {
				parent->color(ul::rbtree_node::red);
				sibling->color(ul::rbtree_node::black);
				rotate_right(parent, root);
				sibling = parent->left;
			}

			if (sibling->color() == ul::rbtree_node::black) {
				if (!sibling->left || sibling->left->color() == ul::rbtree_node::black) {
					if (!sibling->right || sibling->right->color() == ul::rbtree_node::black) {

						if (parent->color() == ul::rbtree_node::black) {
							sibling->color(ul::rbtree_node::red);
							node = parent;
							parent = node->parent();
							continue;

						} else {
							sibling->color(ul::rbtree_node::red);
							parent->color(ul::rbtree_node::black);
							break;
						}

					} else {
						sibling->color(ul::rbtree_node::red);
						sibling->right->color(ul::rbtree_node::black);
						rotate_left(sibling, root);
						sibling = parent->left;
					}
				}
				sibling->color(parent->color());
				parent->color(ul::rbtree_node::black);
				if (sibling->left) sibling->left->color(ul::rbtree_node::black);
				rotate_right(parent, root);
			}
		}
		break;
	}
}
ViewableObjectFactory* HistoryManager::GetFactory(ID id)
{
	UL_ASSERT(data.find(id) != data.end());
	UL_ASSERT(data[id].factory != NULL);
	return data[id].factory;
}
int HistoryManager::GetModifiedTime(ID id)
{
	UL_ASSERT(data.find(id) != data.end());
	return data[id].modifiedTime;
}
std::string HistoryManager::GetValue(ID id)
{
	UL_ASSERT(data.find(id) != data.end());
	return data[id].value;
}
void HistoryManager::SetFactory(ID id, ViewableObjectFactory* factory)
{
	UL_ASSERT(data.find(id) != data.end());
	data[id].factory = factory;
}
void HistoryManager::SetValue(ID id, std::string value)
{
	UL_ASSERT(data.find(id) != data.end());
	data[id].value = value;
}
void HistoryManager::SetHistory(ID id, std::set<ValueID> history)
{
	UL_ASSERT(data.find(id) != data.end());
	data[id].history = history;
	data[id].modifiedTime = time;
}
void HistoryManager::SetVisible(ID id, bool visible)
{
	UL_ASSERT(data.find(id) != data.end());
	data[id].visible = visible;
}
bool HistoryManager::IsVisible(ID id)
{
	UL_ASSERT(data.find(id) != data.end());
	return data[id].visible;
}
std::set<ValueID> HistoryManager::GetHistory(ID id)
{
	UL_ASSERT(data.find(id) != data.end());
	return data[id].history;
}