IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 红黑树的自底向上插入 -> 正文阅读

[数据结构与算法]红黑树的自底向上插入

//.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以简化讨论,使用伪状态机(懒得改了)来实现简洁化代码。已经检验过,可以直接使用

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-03 11:27:45  更:2021-08-03 11:30:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 18:32:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码