红黑树的自底向上插入

//.h声明
class RedBlackTree {
public:
	enum ColorType {red,black};
	struct RedBlackNode {
		elemenType val;
		RedBlackNode*left;
		RedBlackNode*right;
		ColorType color;
	};
	typedef RedBlackNode* pNode;
	

	RedBlackTree();
	~RedBlackTree();

	void Insert(elemenType);
	pNode Insert(elemenType,pNode);
	void ShowTree();
	pNode get_root();

private:
	pNode root;
	static pNode NullNode;

	void Init();
	pNode CreateNode(elemenType);
	void MakeEmpty();
	void MakeEmpty(pNode);
	short StateMachine(pNode,pNode,pNode);
	pNode L_L_Rotate(pNode);
	pNode L_R_Rotate(pNode);
	pNode R_R_Rotate(pNode);
	pNode R_L_Rotate(pNode);
	void DrawBlack(pNode);
	void DrawRed(pNode);

};
//定义.cpp 
RedBlackTree::pNode RedBlackTree::NullNode = nullptr;  //全体对象共享

 //private:
void RedBlackTree::Init(){
	if (NullNode == nullptr) {
		NullNode = new RedBlackTree::RedBlackNode;
		NullNode->color = black;
		NullNode->left = NullNode->right = NullNode;
	}
 }

RedBlackTree::pNode RedBlackTree::CreateNode(elemenType n) {
	pNode temp = new RedBlackNode;
	temp->left = temp->right = NullNode;
	temp->val = n;
	temp->color = red;
	return temp;
}

void RedBlackTree::MakeEmpty() {
	MakeEmpty(root);
	root = NullNode;
}

void RedBlackTree::MakeEmpty(pNode root) {
	if (root == NullNode)
		return;
	MakeEmpty(root->left);
	MakeEmpty(root->right);
	delete root;
}

short RedBlackTree::StateMachine(pNode son, pNode parent, pNode grandpa) {
	if (grandpa->val > parent->val &&parent->val > son->val)
		if (grandpa->right->color == black)
			return 1;
		else return 2;
	else if (grandpa->val < parent->val&&parent->val < son->val)
		if (grandpa->left->color == black)
			return 3;
		else return 4;
	else if (grandpa->val > parent->val &&parent->val < son->val)
		if (grandpa->right->color == black)
			return 5;
		else return 6;
	else {
		if (grandpa->left->color == black)
			return 7;
		else return 8;
	}
	return 0;
}

RedBlackTree::pNode RedBlackTree::L_L_Rotate(pNode T)	
{
	pNode temp = T->left;
	T->left = temp->right;
	temp->right = T;
	return temp;

}

RedBlackTree::pNode RedBlackTree::R_R_Rotate(pNode T) {
	pNode temp = T->right;
	T->right = temp->left;
	temp->left = T;
	return temp;
}

RedBlackTree::pNode RedBlackTree::L_R_Rotate(pNode T) {
	T->left = R_R_Rotate(T->left);
	T = L_L_Rotate(T);
	return T;
}

RedBlackTree::pNode RedBlackTree::R_L_Rotate(pNode T) {
	T->right = L_L_Rotate(T->right);
	T = R_R_Rotate(T);
	return T;
}

//public:
RedBlackTree::RedBlackTree() {
	if (NullNode == nullptr) {
		NullNode = new RedBlackNode;
		NullNode->color = black;
		NullNode->left = NullNode->right = NullNode;
	}
	root = NullNode;
}

RedBlackTree::~RedBlackTree() {
	MakeEmpty();
}

void RedBlackTree::Insert(elemenType n) {
	if (root == NullNode) {
		root = new RedBlackNode;
		root->left = root->right = NullNode;
		root->color = black;
		root->val = n; return;
	}
	root = Insert(n, root);
}

void RedBlackTree::DrawBlack(pNode root) {
	root->color = black;
	root->left->color = root->right->color = red;
}

void RedBlackTree::DrawRed(pNode root) {
	root->color = red;
	root->left->color = root->right->color = black;
}

RedBlackTree::pNode RedBlackTree::Insert(elemenType n,pNode root) {
	using std::vector;
	vector<pNode>stack;
	while (root != NullNode) {
		stack.push_back(root);
		if (root->val == n) {
			std::cout << "already exist\n";
			return RedBlackTree::root;
		}
		if (root->val > n) {
			root = root->left;
		}
		else root = root->right;
	}

	root = stack.back();
	if (root->val > n) {
		root->left = CreateNode(n);
		stack.push_back(root->left);
	}
	else {
		root->right = CreateNode(n);
		stack.push_back(root->right);
	}
	if (stack.size() <= 2) 
		return stack.at(0);

	pNode temp=NullNode;
	short son, parent, grandpa;
	short solve;
	while (stack.size() > 2) {
		son = stack.size() - 1;
		parent = son - 1;
		grandpa = parent - 1;
		if (stack.at(son)->color||stack.at(parent)->color) 
			return stack.at(0);
		solve = StateMachine(stack.at(son), stack.at(parent), stack.at(grandpa));
		switch (solve) {
		case 1:temp = L_L_Rotate(stack.at(grandpa)); DrawBlack(temp); break;
		case 2:temp = L_L_Rotate(stack.at(grandpa)); DrawRed(temp); break;
		case 3:temp = R_R_Rotate(stack.at(grandpa)); DrawBlack(temp); break;
		case 4:temp = R_R_Rotate(stack.at(grandpa)); DrawRed(temp); break;
		case 5:temp = L_R_Rotate(stack.at(grandpa)); DrawBlack(temp); break;
		case 6:temp = L_R_Rotate(stack.at(grandpa)); DrawRed(temp); break;
		case 7:temp = R_L_Rotate(stack.at(grandpa)); DrawBlack(temp); break;
		case 8:temp = R_L_Rotate(stack.at(grandpa)); DrawRed(temp); break;
		default:std::cout << "error !!!\n"; break;
		}

		if (grandpa) {
			int index = grandpa - 1;
			stack[index]->left == stack[grandpa] ? stack[index]->left = temp : stack[index]->right = temp;
		}
		for (int i = 3; i > 0; i--)
			stack.pop_back();
		stack.push_back(temp);

	}
	stack.at(0)->color = black;
	return stack.at(0);
}

void RedBlackTree::ShowTree() {
	using std::vector;
	if (root == NullNode)
		return;
	pNode temp;
	vector<pNode> stack;
	short index = 1, front = 0;
	stack.push_back(root);
	while (stack.size() > front) {
		while (index) {
			temp = stack.at(front++);
			if (temp != NullNode) {
				stack.push_back(temp->left);
				stack.push_back(temp->right);

				std::cout << temp->val;
				if (temp->color == black)
					std::cout << 'B';
				else std::cout << 'R';
				std::cout << ' ';
			}
			else {
				std::cout << 'N' << " ";
			}
			index--;
		}
		index = stack.size() - front;
		std::cout << std::endl;
	}
}

通常的红黑树的插入时自顶向下,为了实践实现了一下自底向上的方法,使用了NullNode以简化讨论,使用伪状态机(懒得改了)来实现简洁化代码。已经检验过,可以直接使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值