算法导论第十三章-红黑树-Cpp代码实现

经过两三天的探索,终于把红黑树的实现完成了。难点主要在于理解删除时对于多一重颜色的理解。

另外,对于插入和删除的修正原理有一定的了解。特别是删除时候4种情况的判断以及对应措施,非常经典。


red_black_tree.h

#pragma once

/*************************************************
Author:董小歪
Date:2016-06-13
Description:算法导论第十三章-红黑树-Cpp代码实现
**************************************************/

#ifndef RED_BLACK_TREE
#define RED_BLACK_TREE

#include <iostream>

using namespace std;

enum Color {RED, BLACK};

struct TreeNode
{
	Color color;
	int key;
	TreeNode *left, *right, *p;

	TreeNode(int _key = 0) :color(RED), key(_key), left(nullptr), right(nullptr), p(nullptr) {}
};

class RedBlackTree
{
public:
	RedBlackTree();						//构造函数
	void rb_insert(int key);			//插入
	void inorder_tree_walk();			//中序遍历红黑树
	void rb_delete(int key);			//删除结点
	TreeNode* tree_search(int val);		//元素搜索
private:
	TreeNode *root;
	void rb_insert_fixup(TreeNode* z);		//插入修正
	void left_rotate(TreeNode* x);			//左旋
	void right_rotate(TreeNode* x);			//右旋
	void inorder_tree_walk(TreeNode* node);	//中序遍历红黑树
	void rb_transplant(TreeNode* u, TreeNode* v);
	void rb_delete_fixup(TreeNode* x);		//删除修正	
	TreeNode* tree_search(TreeNode* node, int val);
	TreeNode* tree_minimun(TreeNode* node);	//最小元素
};

#endif // !RED_BLACK_TREE


red_black_tree.cpp

#include "red_black_tree.h"

RedBlackTree::RedBlackTree():root(nullptr){}

void RedBlackTree::left_rotate(TreeNode* x)
{
	//左旋和右旋一共要改变6个指针的指向
	TreeNode *y = x->right;
	x->right = y->left;
	if (y->left)
		y->left->p = x;
	y->p = x->p;
	if (x->p == nullptr)
		root = y;
	else if (x->p->left == x)
		x->p->left = y;
	else
		x->p->right = y;
	y->left = x;
	x->p = y;
}

void RedBlackTree::right_rotate(TreeNode* x)
{
	TreeNode* y = x->left;
	x->left = y->right;
	if (y->right)
		y->right->p = x;
	y->p = x->p;
	if (x->p == nullptr)
		root = y;
	else if (x->p->left == x)
		x->p->left = y;
	else
		x->p->right = y;
	y->right = x;
	x->p = y;
}

void RedBlackTree::rb_insert(int key)
{
	TreeNode* z = new TreeNode(key);
	TreeNode* y = nullptr;
	TreeNode* x = root;
	while (x)
	{
		y = x;
		if (key < x->key)
			x = x->left;
		else
			x = x->right;
	}
	z->p = y;
	if (y == nullptr)
		root = z;
	else if (key < y->key)
		y->left = z;
	else
		y->right = z;
	rb_insert_fixup(z);
}

void RedBlackTree::rb_insert_fixup(TreeNode* z)
{
	while (z->p && z->p->color == RED)
	{
		if (z->p->p->left == z->p)
		{
			TreeNode *y = z->p->p->right;
			if (y && y->color == RED)	//case 1
			{
				z->p->color = BLACK;
				y->color = BLACK;
				z->p->p->color = RED;
				z = z->p->p;
			}
			else
			{
				if (z == z->p->right)	//case 2
				{
					z = z->p;
					left_rotate(z);
				}						//case 3
				z->p->color = BLACK;
				z->p->p->color = RED;
				right_rotate(z->p->p);
			}
		}
		else
		{
			TreeNode *y = z->p->p->left;
			if (y && y->color == RED)
			{
				z->p->color = BLACK;
				y->color = BLACK;
				z->p->p->color = RED;
				z = z->p->p;
			}
			else
			{
				if (z == z->p->left)
				{
					z = z->p;
					right_rotate(z);
				}
				z->p->color = BLACK;
				z->p->p->color = RED;
				left_rotate(z->p->p);
			}
		}
	}
	root->color = BLACK;
}

void RedBlackTree::inorder_tree_walk()
{
	inorder_tree_walk(root);
}

void RedBlackTree::inorder_tree_walk(TreeNode* node)
{
	if (node)
	{
		inorder_tree_walk(node->left);
		cout << node->key << ":" << (node->color == RED ? "RED" : "BLACK") << " ";
		inorder_tree_walk(node->right);
	}
}

void RedBlackTree::rb_delete(int key)
{
	TreeNode *z = tree_search(key);
	TreeNode *x;
	if (z == nullptr)
	{
		cout << "关键字为" << key << "的元素不存在,无法删除!" << endl;
		return;
	}
	TreeNode *y = z;
	Color original_color = y->color;
	if (z->left == nullptr)
	{
		x = z->right;
		rb_transplant(z, z->right);
	}
	else if (z->right == nullptr)
	{
		x = z->left;
		rb_transplant(z, z->left);
	}
	else
	{
		y = tree_minimun(z->right);
		original_color = y->color;
		x = y->right;
		if (y->p == z)
		{
			if (x)
				x->p == y;
		}
		else
		{
			rb_transplant(y, y->right);
			y->right = z->right;
			y->right->p = y;
		}
		rb_transplant(z, y);
		y->left = z->left;
		y->left->p = y;
		y->color = z->color;
	}
	if (original_color == BLACK)
		rb_delete_fixup(x);
}

void RedBlackTree::rb_transplant(TreeNode* u, TreeNode* v)
{
	if (u->p == nullptr)
		root = v;
	else if (u == u->p->left)
		u->p->left = v;
	else
		u->p->right = v;
	if (v)
		v->p = u->p;
}

void RedBlackTree::rb_delete_fixup(TreeNode* x)
{
	if (x == nullptr)
		return;
	while (x != root && x->color == BLACK)
	{
		if (x == x->p->left)
		{
			TreeNode* w = x->p->right;
			if (w->color == RED)		//case 1
			{
				w->color = BLACK;
				x->p->color = RED;
				left_rotate(x->p);
				w = x->p->right;
			}
			if (w->left->color == BLACK && w->right->color == BLACK) //case 2
			{
				w->color = RED;
				x = x->p;
			}
			else 
			{
				if (w->right->color == BLACK)	//case 3
				{
					w->left->color = BLACK;
					w->color = RED;
					right_rotate(w);
					w = x->p->right;
				}
				w->color = x->p->color;			//case 4
				x->p->color = BLACK;
				w->right->color = BLACK;
				left_rotate(x->p);
				x = root;
			}
		}
		else
		{
			TreeNode* w = x->p->left;
			if (w->color == RED)
			{
				w->color = BLACK;
				x->p->color = RED;
				right_rotate(x->p);
				w = x->p->left;
			}
			if (w->right->color == BLACK && w->left->color == BLACK)
			{
				w->color = RED;
				x = x->p;
			}
			else 
			{
				if (w->left->color == BLACK)
				{
					w->right->color = BLACK;
					w->color = RED;
					left_rotate(w);
					w = x->p->left;
				}
				w->color = x->p->color;
				x->p->color = BLACK;
				w->left->color = BLACK;
				right_rotate(x->p);
				x = root;
			}
		}
	}
	x->color = BLACK;
}

TreeNode* RedBlackTree::tree_search(int val)
{
	return tree_search(root, val);
}

TreeNode* RedBlackTree::tree_search(TreeNode* node, int val)
{
	if (!node || node->key == val)
		return node;
	if (val < node->key)
		return tree_search(node->left, val);
	else
		return tree_search(node->right, val);
}

TreeNode* RedBlackTree::tree_minimun(TreeNode* node)
{
	TreeNode* temp = node;
	while (temp && temp->left)
		temp = temp->left;
	return temp;
}

测试:

main_entrance.cpp

#include "red_black_tree.h"

int main()
{
	cout << "创建红黑树:" << endl; RedBlackTree rbt;
	cout << endl << "插入元素11:";	rbt.rb_insert(11); rbt.inorder_tree_walk();
	cout << endl << "插入元素10:";	rbt.rb_insert(10); rbt.inorder_tree_walk();
	cout << endl << "插入元素12:";	rbt.rb_insert(12); rbt.inorder_tree_walk();
	cout << endl << "插入元素9:";	rbt.rb_insert(9); rbt.inorder_tree_walk();
	cout << endl << "插入元素7:";	rbt.rb_insert(7); rbt.inorder_tree_walk();
	cout << endl << "插入元素15:";	rbt.rb_insert(15); rbt.inorder_tree_walk();
	cout << endl << "插入元素5:";	rbt.rb_insert(5); rbt.inorder_tree_walk();
	cout << endl << "插入元素8:";	rbt.rb_insert(8); rbt.inorder_tree_walk();
	cout << endl << "插入元素4:";	rbt.rb_insert(4); rbt.inorder_tree_walk();

	cout << endl << "删除元素5(黑):"; rbt.rb_delete(5); rbt.inorder_tree_walk();
	cout << endl << "删除元素11(红):"; rbt.rb_delete(11); rbt.inorder_tree_walk();
	cout << endl;

	system("pause");
}


测试结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值