源码系列:红黑树

red_black_tree.cpp

#include 
#include 
#include 
#include 

using namespace std;

namespace algo
{
	/// @param	TKey	节点键的类型
	/// @param TValue	节点值的类型
	template
	class RBTree
	{
	public:
		enum RBTreeNodeColor
		{
			BLACK,
			RED
		};

		struct RBTreeNode
		{
			TKey				Key;
			TValue				Value;
			RBTreeNodeColor		Color;
			RBTreeNode			*Parent;
			RBTreeNode			*Left;
			RBTreeNode			*Right;

			inline bool IsValid() const
			{
				return (this != s_nil);
			}
		};

		RBTree()
		{
			if(!s_nil)
			{
				s_nil = new RBTreeNode();
				s_nil->Color = BLACK;
			}

			_root = s_nil;
		}

		~RBTree()
		{
			_RecursiveReleaseNode(_root);
		}

		bool Insert(TKey key,TValue value)
		{
			if(Search(key)->IsValid())
			{
				return false;
			}
			else
			{
				RBTreeNode *new_node = new RBTreeNode();
				new_node->Key = key;
				new_node->Value = value;
				new_node->Color = RED;
				new_node->Left = new_node->Right = s_nil;

				_InsertAsNormalBSTree(new_node);
				_InsertFixup(new_node);
				return true;
			}
		}

		bool Delete(TKey key)
		{
			RBTreeNode *z = Search(key);
			if(z->IsValid())
			{
				RBTreeNode *y = NULL;
				if(!z->Left->IsValid() || !z->Right->IsValid())
				{
					y = z;
				}
				else
				{
					y = _Successor(z);
				}

				RBTreeNode *x = (y->Left->IsValid() ? y->Left : y->Right);
				x->Parent = y->Parent;

				if(!y->Parent->IsValid())
				{
					_root = x;
				}
				else
				{
					if(y == y->Parent->Left)
					{
						y->Parent->Left = x;
					}
					else
					{
						y->Parent->Right = x;
					}
				}

				if(y != z)
				{
					z->Key = y->Key;
					z->Value = y->Value;
				}

				if(y->Color == BLACK)
				{
					_DeleteFixup(x);
				}

				delete y;
				return true;
			}
			else
			{
				return false;
			}
		}

		RBTreeNode * Search(TValue const &value)
		{
			RBTreeNode *node = _root;
			while(node != s_nil && node->Value != value)
			{
				node = (value < node->Value ? node->Left : node->Right);
			}
			return node;
		}

		bool Empty()
		{
			return !(_root->IsValid());
		}

		void Display() const
		{
			_Display(_root);
		}

	private:
		void _RecursiveReleaseNode(RBTreeNode *node)
		{
			if(node->IsValid())
			{
				_RecursiveReleaseNode(node->Left);
				_RecursiveReleaseNode(node->Right);
				delete node;
			}
		}

		void _Display(RBTreeNode *node) const
		{
			if(node->IsValid())
			{
				cout << "	node" << node->Value << "\t" << (node->Color == RED ? "red" : "black") << "\t" << endl;

				if(node->Left->IsValid())
				{
					cout << "	\node" << node->Value << "\t" << node->Left->Value << endl;
					_Display(node->Left);
				}

				if(node->Right->IsValid())
				{
					cout << "	\node" << node->Value << "\t" << node->Right->Value << endl;
					_Display(node->Right);
				}
			}
		}

		void _InsertAsNormalBSTree(RBTreeNode *node)
		{
			if(!_root->IsValid())
			{
				_root = node;
				_root->Left = _root->Right = _root->Parent = s_nil;
				_root->Color = BLACK;
				return;
			}

			RBTreeNode *current_node = _root;

			while(true)
			{
				RBTreeNode *&next_node_pointer = (node->Key > current_node->Key ? current_node->Right : current_node->Left);
				if(next_node_pointer->IsValid())
				{
					current_node = next_node_pointer;
				}
				else
				{
					node->Parent = current_node;
					next_node_pointer = node;
					break;
				}
			}
		}

		void _InsertFixup(RBTreeNode *node)
		{
			while(node->Parent->Color == RED)
			{
				bool parent_is_left_child_flag = (node->Parent == node->Parent->Parent->Left);
				RBTreeNode *uncle = parent_is_left_child_flag ? node->Parent->Parent->Right : node->Parent->Parent->Left;

				if(uncle->Color == RED)
				{
					//case 1
					node->Parent->Color = BLACK;
					uncle->Color = BLACK;
					node->Parent->Parent->Color = RED;
					node = node->Parent->Parent;
				}
				else
				{
					if(node == (parent_is_left_child_flag ? node->Parent->Right : node->Parent->Left))
					{
						//case 2
						node = node->Parent;
						parent_is_left_child_flag ? _LeftRotate(node) : _RightRotate(node);
					}

					//case 3
					node->Parent->Color = BLACK;
					node->Parent->Parent->Color = RED;
					parent_is_left_child_flag ? _RightRotate(node->Parent->Parent) : _LeftRotate(node->Parent->Parent);
				}
			}

			_root->Color = BLACK;
		}

		void _LeftRotate(RBTreeNode *node)
		{
			if(!(node->IsValid() && node->Right->IsValid()))
			{
				cout << "错误!\n" << endl;
				return;
			}
			else
			{
				RBTreeNode *right_son = node->Right;

				node->Right = right_son->Left;
				if(right_son->Left->IsValid())
				{
					right_son->Left->Parent = node;
				}
				right_son->Parent = node->Parent;
				if(!(node->Parent->IsValid()))
				{
					_root = right_son;
				}
				else
				{
					if(node == node->Parent->Left)
					{
						node->Parent->Left = right_son;
					}
					else
					{
						node->Parent->Right = right_son;
					}
				}
				right_son->Left = node;
				node->Parent = right_son;
			}
		}

		void _RightRotate(RBTreeNode *node)
		{
			if(!(node->IsValid() && node->Left->IsValid()))
			{
				cout << "错误!\n" << endl;
				return;
			}
			else
			{
				RBTreeNode *left_son = node->Left;

				node->Left = left_son->Right;
				if(left_son->Right->IsValid())
				{
					left_son->Right->Parent = node;
				}
				left_son->Parent = node->Parent;
				if(!(node->Parent->IsValid()))
				{
					_root = left_son;
				}
				else
				{
					if(node == node->Parent->Left)
					{
						node->Parent->Left = left_son;
					}
					else
					{
						node->Parent->Right = left_son;
					}
				}
				left_son->Right = node;
				node->Parent = left_son;
			}
		}

		void _DeleteFixup(RBTreeNode *x)
		{
			while(x != _root &&	x->Color == BLACK)
			{
				bool node_is_parent_left_child = (x == x->Parent->Left);
				RBTreeNode *w = node_is_parent_left_child ? x->Parent->Right : x->Parent->Left;

				if(w->Color == RED)
				{
					//case 1
					w->Color = BLACK;
					x->Parent->Color = RED;
					_LeftRotate(x->Parent);
					w = x->Parent->Right;
				}

				//case 2
				if(w->Left->Color == BLACK && w->Right->Color == BLACK)
				{
					w->Color = RED;
					x = x->Parent;
				}
				else
				{
					//case 3
					if((node_is_parent_left_child ? w->Right->Color : w->Left->Color) == BLACK)
					{
						(node_is_parent_left_child ? w->Left->Color : w->Right->Color) = BLACK;
						w->Color = RED;
						node_is_parent_left_child ? _RightRotate(w) : _LeftRotate(w);
						w = (node_is_parent_left_child ? x->Parent->Right : x->Parent->Left);
					}

					//case 4
					w->Color = x->Parent->Color;
					x->Parent->Color = BLACK;
					(node_is_parent_left_child ? w->Right->Color : w->Left->Color) = BLACK;
					node_is_parent_left_child ? _LeftRotate(x->Parent) : _RightRotate(x->Parent);
					x = _root;
				}
			}

			x->Color = BLACK;
		}

		RBTreeNode * _Successor(RBTreeNode *node)
		{
			if(node->Right->IsValid())
			{
				node = node->Right;
				while(node->Left->IsValid())
				{
					node = node->Left;
				}
				return node;
			}
			else
			{
				RBTreeNode *y = node->Parent;
				while(!y->IsValid() && node == y->Right)
				{
					node = y;
					y = y->Parent;
				}
				return y;
			}
		}

		RBTreeNode *_root;
		static RBTreeNode *s_nil;
	};

	template
	typename RBTree::RBTreeNode * RBTree::s_nil = NULL;
}

测试代码:

#include "red_black_tree.cpp"

using namespace std;

int main()
{
	int init[] = {12,1,9,2,0,11,7,19,4,15,18,5,14,13,10,16,6,3,8,17};
	algo::RBTree bst;
	for(int i=0;i	bst.Display();
        	getchar();
	}

	for(int i=0;i	{
        	bst.Delete(init[i]);
        	bst.Display();
        	getchar();
    	}
	return 0;
}

插入前15个节点示例:

源码系列:红黑树_第1张图片


源码系列:红黑树_第2张图片


源码系列:红黑树_第3张图片


源码系列:红黑树_第4张图片


源码系列:红黑树_第5张图片


源码系列:红黑树_第6张图片


源码系列:红黑树_第7张图片


源码系列:红黑树_第8张图片


源码系列:红黑树_第9张图片


源码系列:红黑树_第10张图片


源码系列:红黑树_第11张图片


源码系列:红黑树_第12张图片


源码系列:红黑树_第13张图片


源码系列:红黑树_第14张图片


源码系列:红黑树_第15张图片


这里就只演示前15个节点的插入操作吧,实测无误(参考July的红黑树系列http://blog.csdn.net/v_july_v/article/details/6284050)。

至于删除就不演示了,源代码里有,只是并不是逆过程,读者可以自己试试。

你可能感兴趣的:(源码系列)