c++实现红黑树

现在只是简单的实现了红黑树的调整功能,其余功能还没有实现好,等后面的学习中再来添加

#ifndef _RB_TREE_H_
#define _RB_TREE_H_

#include <iostream>

typedef bool _color_type;
const _color_type _color_red_ = false;
const _color_type _color_black_ = true;

template <class T>
struct RB_Tree_node {
public:
	_color_type color;
	T key;
	RB_Tree_node *left;
	RB_Tree_node *right;
	RB_Tree_node *parent;

	RB_Tree_node() {}
	RB_Tree_node(T _key) :key(_key) {}
	RB_Tree_node(_color_type _color, T _key, RB_Tree_node *_left, RB_Tree_node* _right, RB_Tree_node* _parent):color(_color), key(_key), left(_left), right(_right), parent(_parent) {}

	RB_Tree_node(RB_Tree_node *tmp) {
		this->color = tmp->color;
		this->key = tmp->key;
		this->left = tmp->left;
		this->right = tmp->right;
		this->parent = tmp->parent;
	}
};

template <class T>
struct RB_tree {
public:
	RB_tree():node_count(0) { __Init(); }
	RB_tree(RB_Tree_node<T>* _header) :header(_header),node_count(0){}
	RB_tree(RB_tree<T>* x);

private:
	RB_Tree_node<T> *header;                    //header节点较为特殊
	int node_count;

public:
	RB_Tree_node<T>*& root() { return (RB_Tree_node<T>* &)header->parent; }
	RB_Tree_node<T>*& leftmost() { return (RB_Tree_node<T>* &)header->left; }
	RB_Tree_node<T>*& rightmost() { return (RB_Tree_node<T>* &)header->right; }

	T minimum();
	T maximum();
	void insert(T value);
	RB_Tree_node<T>* search(T key);

	void preOrder();
	void inOrder();
	void postOrder();

private:
	void __Init();

	RB_Tree_node<T>* _minimum();
	RB_Tree_node<T>* _maximum();
	RB_Tree_node<T>* _insert(RB_Tree_node<T>* x, RB_Tree_node<T>* y,T value);
	void _preOrder(RB_Tree_node<T>* x);
	void _inOrder(RB_Tree_node<T>* x);
	void _postOrder(RB_Tree_node<T>* x);

	void __re_tree_rotate_left(RB_Tree_node<T>* x, RB_Tree_node<T>* &root);
	void __re_tree_rotate_right(RB_Tree_node<T>* x, RB_Tree_node<T>* &root);
	void __rb_tree_rebalance(RB_Tree_node<T> *x, RB_Tree_node<T>* &root);

};
template<class T>
void RB_tree<T>::__Init() {
	header = new RB_Tree_node<T>();
	header->color = _color_red_;
	header->parent = 0;
	leftmost() = header;
	rightmost() = header;
}

template<class T>
T RB_tree<T>::minimum() {
	return _minimum()->key;
}
template<class T>
RB_Tree_node<T>* RB_tree<T>::_minimum() {
	RB_Tree_node<T>* tmp = root();
	while (tmp->left != 0) 
		tmp = tmp->left;
	return tmp;
}

template<class T>
T RB_tree<T>::maximum() {
	return _maximum()->key;
}
template<class T>
RB_Tree_node<T>* RB_tree<T>::_maximum() {
	RB_Tree_node<T>*tmp = root();
	while (tmp->right != 0)
		tmp = tmp->right;
	return tmp;
}

//插入元素不允许有相同元素
template<class T>
void RB_tree<T>::insert(T value) {
	RB_Tree_node<T>* y = header;
	RB_Tree_node<T>* x = root();
	
	while (x != 0) {
		y = x;
		x = x->key > value ? x->left : x->right;
	}
	if(y != 0)
		_insert(x, y, value);
}

template<class T>
RB_Tree_node<T>* RB_tree<T>::_insert(RB_Tree_node<T>* x, RB_Tree_node<T>* y, T value) {
	RB_Tree_node<T>* tmp = new RB_Tree_node<T>(value);
	if (y == header) {
		root() = tmp;
		leftmost() = tmp;
		rightmost() = tmp;
	}
	else if (y == leftmost() && value  < y->key) {
		leftmost() = tmp;
		y->left = tmp;
	}
	else if (y == rightmost() && value > y->key) {
		rightmost() = tmp;
		y->right = tmp;
	}
	else {
		if (value < y->key)
			y->left = tmp;
		else
			y->right = tmp;
	}
	tmp->parent = y;
	tmp->left = 0;
	tmp->right = 0;
	__rb_tree_rebalance(tmp, root());
	++node_count;
	return tmp;
}

/*
*几种树遍历的实现
*/
template<class T>
void RB_tree<T>::preOrder() {
	_preOrder(root());
	std::cout << endl;
}
template<class T>
void RB_tree<T>::_preOrder(RB_Tree_node<T>* x) {
	if (x == 0) return;
	std::cout << x->key << " ";
	_preOrder(x->left);
	_preOrder(x->right);
}

template<class T>
void RB_tree<T>::inOrder() {
	_inOrder(root());
	std::cout << std::endl;
}
template<class T>
void RB_tree<T>::_inOrder(RB_Tree_node<T>* x) {
	if (x == 0)return;
	_inOrder(x->left);
	std::cout << x->key << " ";
	_inOrder(x->right);
}

template<class T>
void RB_tree<T>::postOrder() {
	_postOrder(root());
	std::cout << std::endl;
}
template<class T>
void RB_tree<T>::_postOrder(RB_Tree_node<T>* x) {
	if (x == 0) return;
	_postOrder(x->left);
	_postOrder(x->right);
	std::cout << x->key << " ";
}

/*
*这里的左旋和右旋操作和AVL基本相似,但是还要维护x节点的父亲节点以及每个节点的parent指针
*/
template<class T>
void RB_tree<T>::__re_tree_rotate_left(RB_Tree_node<T>* x, RB_Tree_node<T>* &root) {
	RB_Tree_node<T>* y = x->right;
	x->right = y->left;
	if (y->left != 0)
		y->left->parent = x;
	y->parent = x->parent;

	if (x == root)
		root = y;
	else if (x == x->parent->left)
		x->parent->left = y;
	else
		x->parent->right = y;

	y->left = x;
	x->parent = y;
}

template<class T>
void RB_tree<T>::__re_tree_rotate_right(RB_Tree_node<T>* x, RB_Tree_node<T>* &root) {
	RB_Tree_node<T>* y = x->left;
	x->left = y->right;
	if (y->right != 0)
		y->right->parent = x;
	y->parent = x->parent;

	if (x == root) //更新x的parent指向x节点                根节点的parent为header
		root = y;
	else if (x == x->parent->left)//判断为x的右节点
		x->parent->left = y;
	else
		x->parent->right = y;

	y->right = x;
	x->parent = y;
}

template<class T>
void RB_tree<T>::__rb_tree_rebalance(RB_Tree_node<T> *x, RB_Tree_node<T>* &root)   //RB树的平衡的调整    
{
	std::cout << "//__rb_tree_rebalance" << std::endl;
	x->color = _color_red_; //首先将新节点的颜色设置为红色,新节点必须为红色,然后判断下面节点是否出现错误情况
	while (x != root && x->parent->color == _color_red_) { //父亲节为红色,并且当前节点不为根结点    因为只有当父亲节点也为红色的时候才会出现错误,并且后面不断返回的x节点一直会为红色 
		if (x->parent == x->parent->parent->left) {//父亲节点为祖父节点之左子节点
			RB_Tree_node<T>* y = x->parent->parent->right; //设置y为伯父节点
			if (y != 0 && y->color == _color_red_) {//伯父节点存在并且伯父节点为红色 (满足父亲节点和伯父节点都为红色的情况,那么将父亲节点和伯父节点变为黑色,曾祖父节点更改为红色)
				y->color = _color_black_;
				x->parent->color = _color_black_;
				x->parent->parent->color = _color_red_;
				x = x->parent->parent;//将x设置为曾曾祖父,继续向上传递,查看是否含有上述情况
			}
			else { //无伯父节点,或者伯父节点为黑色(默认没有节点就是黑色)       也就是出现错误,需要我们的调整
				if (x == x->parent->right) {//如果新节点为父亲节点之右子节点
					x = x->parent;
					std::cout << "         //__re_tree_rotate_left" << std::endl;
					__re_tree_rotate_left(x, root);
				}
				x->parent->parent->color = _color_red_;//更改颜色
				x->parent->color = _color_black_;
				std::cout << "         //__re_tree_rotate_right" << std::endl;
				__re_tree_rotate_right(x->parent->parent, root);

			}
		}
		else { //父亲节点为祖父节点右子节点
			RB_Tree_node<T>* y = x->parent->parent->left;//y为伯父节点
			if (y != 0 && y->color == _color_red_) { //伯父节点为红色
				y->color = _color_black_;
				x->parent->color = _color_black_;
				x->parent->parent->color = _color_red_;
				x = x->parent->parent; //准备继续向上检查,将x设置为祖父节点
			}
			else {  //伯父节点不存在或者为黑色,也就是出现错误,需要我们的调整!!
				if (x == x->parent->left) { //如果新节点为父亲节点的左侧节点
					x = x->parent;
					std::cout << "         //__re_tree_rotate_right" << std::endl;
					__re_tree_rotate_right(x, root);//右旋操作
				}
				x->parent->parent->color = _color_red_; //修改颜色,继续左旋
				x->parent->color = _color_black_;
				std::cout << "         //__re_tree_rotate_left" << std::endl;
				__re_tree_rotate_left(x->parent->parent, root);

			}
		}
	}
	root->color = _color_black_;  //可能会出现修改根节点颜色的情况,可以将根节点直接修改为黑色,不影响RB树的正确性
}

#endif

测试程序

#include <iostream>
#include <thread>
#include <algorithm>
#include "RB_Tree.h"

using namespace std;

int main()
{

	int iv[] = { 10,7,8,15,5,6,11,13,12 };
	RB_tree<int> *tree = new RB_tree<int>();

	for (int i = 0; i < 9; i++) 
		tree->insert(iv[i]);
		
	tree->preOrder();
	int min = tree->minimum();
	int max = tree->maximum();
	cout << min << "  " << max << endl;

	system("pause");
}

猜你喜欢

转载自blog.csdn.net/li1615882553/article/details/83386011