アルゴリズム導論-赤黒樹C++実現


赤と黒のツリーの定義:
1本の二叉探査木は、次の赤と黒の性質を満たすと、赤と黒の木になります.
1)各ノードは赤、または黒です.
2)ルートノードは黒です.
3)各リーフノード(NIL)はブラックノードである.
4)1つのノードが赤い場合,その2人の息子はいずれも黒い.
5)各ノードに対して、そのノードからその子孫ノードまでのすべてのパスに同じノード数の黒いノードが含まれる.
C++コード実装:
BRTreeNode.h
#ifndef BRTREENODE_H_INCLUDED
#define BRTREENODE_H_INCLUDED
#include
using namespace std;
class BRTree;
class BRTreeNode
{
private:
	friend class BRTree;
	int key;
	bool color;
	BRTreeNode* left;
	BRTreeNode* right;
	BRTreeNode* parent;
public:
	BRTreeNode():key(-1),color(0),left(NULL),right(NULL),parent(NULL){}
	BRTreeNode(BRTreeNode* node):key(node->key),color(node->color),left(node->left),right(node->right),parent(node->parent)
	{}
	BRTreeNode(int num,bool flag):key(num),color(flag),left(NULL),right(NULL),parent(NULL){}
	~BRTreeNode()
	{

	}
	int Getkey()
	{
		return key;
	}
	bool Getcolor()
	{
		return this->color;
	}
	BRTreeNode* GetLeft()
	{
		return this->left;
	}
	BRTreeNode* Getright()
	{
		return this->right;
	}
	BRTreeNode* Getparent()
	{
		return this->parent;
	}
	void Inorder()
	{
		if(this!=NULL)
		{
			this->left->Inorder();
			cout<key<right->Inorder();
		}
	}
	void Preorder()
	{
		if(this!=NULL)
		{
			cout<key<left->Preorder();
			this->right->Preorder();
		}
	}
	void Postorder()
	{
		if(this!=NULL)
		{
			this->left->Postorder();
			this->right->Postorder();
			cout<key<left->MakeEmpty();
			this->right->MakeEmpty();
			delete this;
		}
	}
	int GetHeight()
	{
		int L,R;
		if(this==NULL)
		{
			return 0;
		}
		L=this->left->GetHeight();
		R=this->right->GetHeight();
		return 1+(L>R? L:R);
	}
};


#endif // BRTREENODE_H_INCLUDED

BRTree.h
#ifndef BRTREE_H_INCLUDED
#define BRTREE_H_INCLUDED
#define maxSize 30
#define maxWidth 30
#include"BRTreeNode.h"
class BRTree
{
private:
	BRTreeNode* root;
	BRTreeNode* nil;
public:
	BRTree():nil(new BRTreeNode())
	{
		nil->color=0;
		nil->key=-1;
		nil->left=nil->right=nil->parent=NULL;
		root=nil;
	}
	~BRTree()
	{
		MakeEmpty(root);
		delete nil;
	}
	//   node      
	void MakeEmpty(BRTreeNode*node)
	{
		if(node!=nil)
		{
			MakeEmpty(node->left);
			MakeEmpty(node->right);
			delete node;
		}
	}
	int Getkey(BRTreeNode* node)
	{
		return node->Getkey();
	}
	bool Getcolor(BRTreeNode* node)
	{
		return node->Getcolor();
	}
	BRTreeNode* Getroot()
	{
		return root;
	}
	BRTreeNode* GetParent(BRTreeNode*node)
	{
		return node->parent;
	}
	int GetHeight(BRTreeNode* node)
	{
		int L,R;
		if(node==nil)
			return 0;
		L=GetHeight(node->left);
		R=GetHeight(node->right);
		return 1+(L>R? L:R);
	}
    int GetBlackHeight(BRTreeNode* node)
	{
		int L,R;
		if(node==nil) return 0;
		L=GetHeight(node->left);
		R=GetHeight(node->right);
		if(node->Getcolor()) return(L>R? L:R);
		else return 1+(L>R? L:R);
	}
	void Inorder(BRTreeNode*node)
	{
		if(node!=nil)
		{
			Inorder(node->left);
			cout<key<right);
		}
	}
	void Preorder(BRTreeNode*node)
	{
		if(node!=nil)
		{
			cout<key<left);
			Preorder(node->right);
		}
	}
	void Posetorder(BRTreeNode*node)
	{
		if(node!=nil)
		{
			Posetorder(node->left);
			Posetorder(node->right);
			cout<key<0)
        {
            p=stack[top];
            n=level[top][0];
            for(i=1;i<=n;i++)
                cout<key=0;
                stack[top]=tmp;
                level[top][0]=n+width;
                level[top][1]=2;
                top++;
                stack[top]=p.right;
                level[top][0]=n+width;
                level[top][1]=2;

            }
            if(p.left!=NULL)
            {
                top++;
                stack[top]=p.left;
                level[top][0]=n+width;
                level[top][1]=1;
            }
        }
    }
}
	//    node
	bool LeftRotate(BRTreeNode* node)
	{
		BRTreeNode*y;
		if(node->right==nil)
		{
			cout<right;
		node->right=y->left;
		if(y->left!=nil)
		{
			y->left->parent=node;
		}
		y->parent=node->parent;
		if(node->parent==nil)
		{
			root=y;
		}
		else if(node->parent->left==node)
		{
			node->parent->left=y;
		}
		else
		{
			node->parent->right=y;
		}
		y->left=node;
		node->parent=y;
		return 1;
	}
	//    
	bool RightRotate(BRTreeNode* node)
	{
		if(node->left==nil)
		{
			cout<left;
		node->left=x->right;
		if(x->right!=nil)
		{
			x->right->parent=node;
		}
		x->parent=node->parent;
		if(node->parent==nil)
		{
			root=x;
		}
		else if(node->parent->left==node)
		{
			node->parent->left=x;
		}
		else
		{
			node->parent->right=x;
		}
		node->parent=x;
		x->right=node;
		return 1;
	}
	void Insert(int num)
	{
		BRTreeNode* node=new BRTreeNode(num,1);
		node->left=nil;
		node->right=nil;
		node->parent=nil;
		BRTreeNode* p=root,*q=nil;
		if(root==nil)
		{
			node->color=0;
			root=node;
			root->left=root->right=root->parent=nil;
			return ;
		}
		while(p!=nil)
		{
			if(p->key==num)
			{
				cout<key>num)
			{
				q=p;
				p=p->left;
			}
			else
			{
				q=p;
				p=p->right;
			}
		}
		if(q->key>num)
		{
			q->left=node;
			node->parent=q;
		}
		else
		{
			q->right=node;
			node->parent=q;
		}
		RBInsertAdjust(node);
	}
	void RBInsertAdjust(BRTreeNode* node)
	{
		BRTreeNode* y;
		while(node->parent->color==1)
		{
			if(node->parent==node->parent->parent->left)
			{
				y=node->parent->parent->right;
				if(y->color==1)
				{
					node->parent->color=0;
					y->color=0;
					y->parent->color=1;
					node=node->parent->parent;
				}
				//  y      
				else
				{
					//     
					if(node==node->parent->right)
					{
						node=node->parent;
						LeftRotate(node);
					}
					//     
					node->parent->color=0;
					node->parent->parent->color=1;
					RightRotate(node->parent->parent);
				}
			}
			else
			{
				y=node->parent->parent->left;
				if(y->color==1)
				{
					node->parent->color=0;
					y->color=0;
					y->parent->color=1;
					node=node->parent->parent;
				}
				else
				{
					if(node==node->parent->left)
					{
						node=node->parent;
						RightRotate(node);
					}
					node->parent->color=0;
					node->parent->parent->color=1;
					LeftRotate(node->parent->parent);
				}
			}
		}
		root->color=0;
	}
	BRTreeNode* Search(int num)
	{
		BRTreeNode* p=root;
		while(p!=nil)
		{
			if(p->key==num)
			{
				return p;
			}
			else if(p->key>num)
			{
				p=p->left;
			}
			else
			{
				p=p->right;
			}
		}
		cout<left!=nil)
		{
			p=p->left;
		}
		return p->key;
	}
	//   node          da  ,     da 
	int Maxnum(BRTreeNode*node)
	{
		BRTreeNode*p=node;
		while(p->right!=nil)
		{
			p=p->right;
		}
		return p->key;
	}
	//   node             ,      
	BRTreeNode* MinNum(BRTreeNode*node)
	{
		BRTreeNode*p=node;
		while(p->left!=nil)
		{
			p=p->left;
		}
		return p;
	}
	//   node             
	BRTreeNode* MaxNum(BRTreeNode*node)
	{
		BRTreeNode*p=node;
		while(p->right!=nil)
		{
			p=p->right;
		}
		return p;
	}
	BRTreeNode*InorderSuccessor(BRTreeNode*node)
	{
		if(node->right!=nil)
		{
			return MinNum(node->right);
		}
		else
		{
			BRTreeNode*p=GetParent(node);
			while(p&&node==p->right)
			{
				node=p;
				p=GetParent(node);
			}
			return p;
		}
	}
	//       
	BRTreeNode*InordePredecessor(BRTreeNode*node)
	{
		if(node->left!=nil)
		{
			return MaxNum(node->left);
		}
		else
		{
			BRTreeNode*p=GetParent(node);
			while(p&&node==p->left)
			{
				node=p;
				p=GetParent(node);
			}
			return p;
		}
	}
	bool Delete(int num)
	{
		BRTreeNode*z,*y,*x;
        //  key  num   p
        z=Search(num);
		//          0
        if(z==nil)
        {
            return 0;
        }
		if(z->left==nil||z->right==nil)
		{
			y=z;
		}
		else
			y=InorderSuccessor(z);
		if(y->left!=nil)
			x=y->left;
		else
			x=y->right;
		x->parent=y->parent;
		if(x->parent==nil)
			root=x;
		else if(y=y->parent->left)
			y->parent->left=x;
		else
			y->parent->right=x;
		if(y!=z)
		{
			z->key=y->key;
		}
		if(y->color==0)
		{
			RBTreeFixup(x);
		}
		return 1;
	}
	void RBTreeFixup(BRTreeNode* x)
	{
		BRTreeNode*w;
		while(x!=root&&x->color==0)
		{
			if(x==x->parent->left)
			{
				w=x->parent->right;
				if(w->color==1)
				{
					w->color=0;
					x->parent->color=1;
					LeftRotate(x->parent);
					w=x->parent->right;
				}
				if(w->left->color==0&&w->right->color==0)
				{
					w->color=1;
					x=x->parent;
				}
				else
				{
					if(w->right->color==0)
					{
						w->color=1;
						RightRotate(w);
						w=x->parent->right;
					}
					w->color=x->parent->color;
					x->parent->color=0;
					w->right->color=0;
					LeftRotate(x->parent);
					x=root;
				}
			}
			else
			{
				w=x->parent->left;
				if(w->color==1)
				{
					w->color=0;
					x->parent->color=1;
					RightRotate(x->parent);
					w=x->parent->left;
				}
				if(w->right->color==0&&w->left->color==0)
				{
					w->color=1;
					x=x->parent;
				}
				else
				{
					if(w->left->color==0)
					{
						w->color=1;
						LeftRotate(w);
						w=x->parent->left;
					}
					w->color=x->parent->color;
					x->parent->color=0;
					w->left->color=0;
					RightRotate(x->parent);
					x=root;
				}
			}
		}
		x->color=0;
	}
};

#endif // BRTREE_H_INCLUDED

テストプログラム
#include 
#include"BRTree.h"
#include "BRTreeNode.h"
using namespace std;

int main()
{
    BRTree tree;
    cout<

実行結果:
参照先:
赤と黒の木を徹底的に理解するように教えます.http://blog.csdn.net/v_JULY_v/article/details/6105630