紅黑樹C++描述

RedBlackTree.h


#ifndef __RED_BLACK_TREE_H
#define __RED_BLACK_TREE_H

#include <iostream>
using namespace std;

enum{RED, BLACK };


// 紅黑樹結點類
template <typename T>
struct RedBlackNode
{
	T            element;
	RedBlackNode<T> *left;
	RedBlackNode<T> *right;
	RedBlackNode<T> *parent;
	int          color;

	RedBlackNode<T>(const T & theElement = T(),
		            RedBlackNode<T> *lt = NULL, RedBlackNode<T> *rt = NULL,
		            RedBlackNode<T> *pt = NULL, int c = BLACK)
		: element (theElement), left(lt), right(rt), parent(pt), color(c)
	{}
};


template<typename T>
class RedBlackTree
{
public:
	explicit  RedBlackTree();
	RedBlackTree(const RedBlackTree<T> & rhs);
	~RedBlackTree();
	const RedBlackTree<T> & operator=(const RedBlackTree<T> & rhs);

	const T & findMin() const;
	const T & findMax() const;
	bool contins(const T & x) const;
	bool isEmpty() const;
	void printTree() const;

	RedBlackNode<T> * minimun(RedBlackNode<T> * &x);  // 最小關鍵字元素
	void makeEmpty();
	void insert(const T x);
	void remove(const T & x);
	RedBlackNode<T> * seach(T value);
	const RedBlackNode<T> * NullNode() const;

private:
	RedBlackNode<T> *header;    // 樹根
	RedBlackNode<T> *nullNode;  // 公共空結點

	RedBlackNode<T> *current;
	RedBlackNode<T> *parent;
	RedBlackNode<T> *grand;
	RedBlackNode<T> *great;

	//用於遞歸調用
	void reclaimMemory(RedBlackNode<T> *t);
	void printTree(RedBlackNode<T> *t) const;
	void deleteNode(RedBlackNode<T> *t) const;

	//RedBlackNode<T> * clone(RedBlackNode<T> * t) const;
	RedBlackNode<T> * clone(RedBlackNode<T> * t, 
	                        const RedBlackNode<T> * theNullNode) const;
	void transplant(RedBlackNode<T> * u, RedBlackNode<T> * v);

	// 紅黑樹的操作函數
	void handleReorient(const T & item);
	RedBlackNode<T> * rotate(const T & item, RedBlackNode<T> *theParent);
	void rotateWithLeftChild(RedBlackNode<T> * k2);
	void rotateWithRightChild(RedBlackNode<T> * k1);
	void removeFixup(RedBlackNode<T> * x);
	void insertFixup(RedBlackNode<T> * z);
};

// 構造函數
template <typename T>
RedBlackTree<T>::RedBlackTree()
{
	nullNode = new RedBlackNode<T>;
	//nullNode->left = nullNode;
	//nullNode->right = nullNode;
	nullNode->color = BLACK;
	header = nullNode;
}
// 拷貝構造函數
template <typename T>
RedBlackTree<T>::RedBlackTree(const RedBlackTree<T> &rhs)
{
	nullNode = new RedBlackNode<T>;
	header = nullNode;
	header = clone(rhs.header, nullNode );
}

template <typename T>
RedBlackTree<T>::~RedBlackTree()
{
	makeEmpty();
	delete nullNode;
	//cout << "~RedBlackTree()" << endl;
}

template <typename T>
inline const RedBlackNode<T> * RedBlackTree<T>::NullNode() const
{
	return this->nullNode;
}

template <typename T>
bool RedBlackTree<T>::isEmpty() const
{
	return header == nullNode;
}


template <typename T>
void RedBlackTree<T>::makeEmpty()
{
	if(header == NULL || header == nullNode)
		return;
	deleteNode(header);
	header = nullNode ;
}

template <typename T>
void RedBlackTree<T>::deleteNode(RedBlackNode<T> *t) const
{
	if( t != nullNode)
	{
		deleteNode(t->left);
		deleteNode(t->right);
		delete t;
	}
}

template <typename T>
void RedBlackTree<T>::printTree() const
{
	if(header == nullNode)
		cout << "Empty tree " << endl;
	else
		printTree(header);
}

template <typename T>
void RedBlackTree<T>::printTree(RedBlackNode<T> *t) const
{
	if(t !=	nullNode)
	{
		printTree(t->left);
		cout << t->element << endl;
		printTree(t->right);
	}
}
// 賦值函數
template <typename T>
const RedBlackTree<T> & RedBlackTree<T>::operator=(const RedBlackTree<T> &rhs)
{
	if(this != &rhs)
	{
		makeEmpty();
		header = clone(rhs.header, nullNode );
	}
	return *this;
}

template <typename T>
RedBlackNode<T> * RedBlackTree<T>::clone(RedBlackNode<T> * t, 
	                                     const RedBlackNode<T> * theNullNode) const
{
	RedBlackNode<T> * tmp = const_cast<RedBlackNode<T> *>(theNullNode);

	if(t->left == NULL || t->right == NULL)
	{
		t = tmp;
	}
	if(t == theNullNode ) // 空結點
	{
		return tmp;
	}
	else
		return new RedBlackNode<T>(t->element, clone(t->left, theNullNode), 
		                    clone(t->right, theNullNode), t->parent, t->color);
}

template <typename T>
void RedBlackTree<T>::rotateWithLeftChild(RedBlackNode<T> * x)
{
	RedBlackNode<T> * y = x->right;
	if(y == nullNode)
	{
		return;
	}

	x->right = y->left;
	if(y->left != nullNode)
		y->left->parent = x;
	y->parent = x->parent;
	if(x->parent == nullNode) // 根結點
	{
		header = y;
	}
	else if(x == x->parent->left)
		x->parent->left = y;
	else
		x->parent->right = y;

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

template <typename T>
void RedBlackTree<T>::rotateWithRightChild(RedBlackNode<T> * x)
{
	RedBlackNode<T> * & y = x->left;
	if(y == nullNode)
		return;

	x->left = y->right;
	if(y->right != nullNode)
		y->right->parent = x;
	y->parent = x->parent ;

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

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


template <typename T>
void RedBlackTree<T>::insert( const T value )
{
	RedBlackNode<T> *y = nullNode;
	RedBlackNode<T> *x = header;
	RedBlackNode<T> *z = nullNode;

	if(header == nullNode)
	{
		header = new RedBlackNode<T>(value, nullNode, nullNode, nullNode, BLACK);
		return;
	}
	while(x != nullNode)
	{
		y = x; // 保存 x
		if( value < x->element)
		{
			x = x->left;
		}
		else if(value > x->element)
		{
			x = x->right;
		}
		else return;
	}
	z = new RedBlackNode<T>(value, nullNode, nullNode, y, RED);
	z->parent = y;

	if(y == nullNode)
	{
		header = z;//get_node(y, value);
		//return;
	}
	else if(value < y->element)
	{
		y->left  = z;//get_node(y, value);
	}
	else
	{
		y->right = z;//get_node(y, value);
	}

	insertFixup(z);//修正插入節點 z 破壞的紅黑樹
}

template <typename T>
void RedBlackTree<T>::insertFixup(RedBlackNode<T> * z)
{
	RedBlackNode<T> *y;
    while(z->parent->color == RED) // z是紅色,如果P(z)爲紅色,則違反規則4
	{
		if( z->parent == z->parent->parent->left )
		{
			y = z->parent->parent->right; // y 爲 z 的叔節點
			if(y->color == RED) // 如果z的叔節點爲紅色
			{
				z->parent->color = BLACK; // 把z的父節點塗黑
				y->color    = BLACK; // 叔節點塗黑
				z->parent->parent->color = RED;// 父節點的父節點塗黑
				z = z->parent->parent;         // z指向父節點的父節點, 不看圖是不容易理清的
			}
			else 
			{
				if(z == z->parent->right)
			    {
					z = z->parent;
					rotateWithLeftChild(z); // 執行一個左旋
			    }
				z->parent->color    = BLACK;
				z->parent->parent->color = RED;
				rotateWithRightChild(z->parent->parent);
			}
		}//if
		else // P(z) == Right( P( P(z) ) )
		{
			y = z->parent->parent->left;  // y 爲 z 的叔節點
			if(y->color == RED) // 如果z的叔節點爲紅色
			{
				z->parent->color = BLACK; // 把z的父節點塗黑
				y->color    = BLACK; // 叔節點塗黑
				z->parent->parent->color = RED;// 父節點的父節點塗黑
				z = z->parent->parent;         // z指向父節點的父節點
			}
			else 
			{
				if(z == z->parent->left)
				{
					z = z->parent;
					rotateWithRightChild(z);
				}
				z->parent->color    = BLACK;
				z->parent->parent->color = RED;
				rotateWithLeftChild(z->parent->parent);
			}
		}//else
	}//while
	header->color = BLACK;
}



// 用於輔助remove函數
// v子樹代替u子樹
template <typename T>
void RedBlackTree<T>::transplant(RedBlackNode<T> * u, RedBlackNode<T> * v)
{
	if(u->parent == nullNode)
	{
		header = v;
	}
	else if(u == u->parent->left)
		u->parent->left = v;
	else
		u->parent->parent = v;
	v->parent = u->parent;
}

template <typename T>
void RedBlackTree<T>::removeFixup(RedBlackNode<T> * x)
{
	RedBlackNode<T> *w = NULL;
	while( x != header && x->color == BLACK)
	{
		if(x == x->parent->left)
		{
			w = x->parent->right;
			if(w->color == RED)
			{
				w->color = BLACK;
				x->parent->color = RED;
				rotateWithLeftChild(x->parent);
				w = x->parent->right;
		    }
		    if( (w->left->color == BLACK) && (w->right->color == BLACK))
		    {
			    w->color = RED;
			    x = x->parent;
		    }
		    else
			{
				if(w->right->color == BLACK)
				{
					w->left->color = BLACK;
					w->color = RED;
					rotateWithRightChild(w);
					w = x->parent->right;
				}
				w->color = x->parent->color;
				x->parent->color = BLACK;
				w->right->color = BLACK;
				rotateWithLeftChild(x->parent);
				x = header;
			}
	    }	
        else
		{
			w = x->parent->left;
			if(w->color == RED)
			{
				w->color = BLACK;
				x->parent->color = RED;
				rotateWithRightChild(x->parent);
				w = x->parent->left;
			}
			if( (w->right->color == BLACK) && (w->left->color == BLACK) )
			{
				w->color = RED;
				x = x->parent;
			}
			else
			{
				if(w->left->color == BLACK )
				{
					w->right->color = BLACK;
					w->color = RED;
					rotateWithRightChild(w);
					w = x->parent->left;
				}
				w->color = x->parent->color;
				x->parent->color = BLACK;
				w->left->color = BLACK;
				rotateWithRightChild(x->parent);
				x = header;
			}
		}
	} // while
	x->color = BLACK;
}

template <typename T>
RedBlackNode<T> * RedBlackTree<T>::seach(T value)
{
	RedBlackNode<T> *x = header;
	while(x != nullNode && x->element != value)
	{
		x = (value < x->element) ? x->left : x->right;
	}
	return x;
}

template <typename T>
RedBlackNode<T> * RedBlackTree<T>::minimun(RedBlackNode<T> * &x)
{
	while(x->left != nullNode)
		x = x->left;
	return x;
}

template <typename T>
void RedBlackTree<T>::remove(const T & value)
{
	RedBlackNode<T> *x = NULL;
	RedBlackNode<T> *z = seach(value);
	if(z == nullNode)
		return;
	RedBlackNode<T> *y = z;
	int yOriginalColor = y->color;   // 用於保存y的顏色
	
	if(z->left == nullNode)
	{
		x = z->right;
		transplant(z, z->right);
	}
	else if(z->right == nullNode)
	{
		x = z->left;
		transplant(z, z->left);
	}
	else // z有兩個孩子
	{
		y = minimun(z->right); // y指向z的後繼
		yOriginalColor = y->color;
		x = y->right;
		if(y->parent == z)
		{
			x->parent = y;
		}
		else
		{
			transplant(y, y->right );
			y->right = z->right;
			y->right->parent = y;
		}
		transplant(z, y);
		y->left = z->left;
		y->left->parent = y;
		y->color = z->color;
	}// else
	if(yOriginalColor == BLACK)
	{
		removeFixup(x);
	}
	delete z;
	z = nullNode;
}

#endif

簡單測試

main.cpp

#include <iostream>
#include <vector>
#include <cstdlib>

#include "RedBlackTree.h"

using namespace std;


int main(int argc, char **argv)
{
  {	RedBlackTree<int> RBTree;
	for(int i = 1; i <= 9; i++)
	{
		RBTree.insert(i);
	}
	RedBlackTree<int> rbtree2(RBTree); // 拷貝構造
	//rbtree2 = RBTree;  
	RBTree.printTree();
	cout << "------------" << endl;
	rbtree2.printTree();
	cout << "------------" << endl;
	cout << (RBTree.seach(5) != RBTree.NullNode() ? 
		"find 5" : " not find 5") << endl;
	RBTree.remove(5);
	cout << "delete 5" <<endl;
	cout << (RBTree.seach(5) != RBTree.NullNode() ? 
		"find 5" : "not find 5") << endl;
	RBTree.printTree();
  }
	cout << "end" << endl;
	cout << "end" << endl;
	//system("pause");
	return 0;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章