源码系列:红黑树

red_black_tree.cpp

#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>

using namespace std;

namespace algo
{
	/// @param	TKey	节点键的类型
	/// @param TValue	节点值的类型
	template<typename TKey,typename TValue>
	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 TKey, typename TValue>
	typename RBTree<TKey, TValue>::RBTreeNode * RBTree<TKey, TValue>::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<int,int> bst;
	for(int i=0;i<sizeof(init)/sizeof(init[0]);i++)
	{
		bst.Insert(init[i],init[i]);
        <span style="white-space:pre">	</span>bst.Display();
        <span style="white-space:pre">	</span>getchar();
	}

	for(int i=0;i<sizeof(init)/sizeof(init[0]);i++)
    <span style="white-space:pre">	</span>{
        <span style="white-space:pre">	</span>bst.Delete(init[i]);
        <span style="white-space:pre">	</span>bst.Display();
        <span style="white-space:pre">	</span>getchar();
    <span style="white-space:pre">	</span>}
	return 0;
}

插入前15个节点示例:































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

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值