붉 은 검 은 나무의 독서 노트

최근 에 고급 데이터 구조의 여행 을 시 작 했 습 니 다. 이번 여행 에서 저 는 고급 데이터 구 조 를 이론 부터 인 코딩 까지 한 번 씩 지속 적 으로 공유 할 것 입 니 다. 그리고 블 로그 형식 을 통 해 부족 한 점 을 지적 해 주 셨 으 면 좋 겠 습 니 다!
       이 진 트 리 는 동적 정렬 된 데이터 구조 로 삽입, 삭제, 찾기 등 을 지원 하 며 평균 시간 복잡 도 는 O (log (N) 이지 만 일반 이 진 트 리 는 나무 가 한 가지 로 퇴화 하 는 것 을 보장 하지 못 합 니 다. 이때 최 악의 경우 시간 복잡 도 는 O (N) 입 니 다.이때 균형 이 잡 힌 이 진 트 리 가 생 겼 다.밸 런 스 이 진 트 리 는 밸 런 스 를 동적 으로 조정 하 는 데이터 구조 이지 만 이상 적 인 밸 런 스 이 진 트 리 는 어렵다. 그래서 사람들 은 밸 런 스 이 진 트 리 대신 AVL, 레 드 블랙 트 리, Treap, 스 트 레 칭 트 리 등 을 사용 하 는데 이런 데이터 구 조 는 최 악의 상황 을 잘 개선 할 수 있다.하지만 이 루 기 란 쉽 지 않다.
      빨간색 과 검은색 나 무 는 균형 에 가 까 운 데이터 구조 로 삽입, 삭제, 찾기 등의 평균 시간 복잡 도 는 모두 O (N) 로 복잡 하지만 그의 조작 은 좋 은 최 악의 상황 효율 을 가진다. 붉 은 검 은 나 무 는 균형 에 대한 제한 을 풀 었 다.더 이상 엄격 한 의미 의 균형 이 진 트 리 가 아 닐 수 있 습 니 다.
 균형 이 진 트 리 는 다음 과 같은 성질 을 만족 시 킵 니 다.
    (1) 빨간색 과 검은색 나무 노드 는 빨간색 노드 이거 나 검은색 노드 이다.    (2) 뿌리 노드 는 검 은 노드 이다.   (3) 잎 노드 (빈 노드) 는 검 은 노드 이다.   (4) 모든 빨 간 노드 의 두 개의 키 노드 는 검 은 노드 이다.    (5) 각 노드 에 대해 이 노드 에서 자손 노드 까지 의 모든 경로 에 같은 수량의 검 은 노드 를 포함한다.
     삽입, 삭제 등 균형 조정 과정 에 대해 서 는 큰 소 를 보 세 요.http://blog.csdn.net/v_july_v / article / details / 654343438 의 블 로그, 나의 주요 사상 학습 은 그 중에서 이 루어 졌 습 니 다. 여기 서 감 사 드 립 니 다!
     다음 세그먼트 코드: RedBlackNode. h
#include<iostream>
using namespace std;
const bool RED=true;
const bool BLACK=false;

struct RedBlackNode
{
	RedBlackNode *parent;
	RedBlackNode *leftChild;
	RedBlackNode *rightChild;
	int key;
	bool color;
	RedBlackNode(int tempKey)
	{
		key=tempKey;
		parent=NULL;
		leftChild=NULL;
		rightChild=NULL;
	    color=RED;
	}
};

  다음은 알고리즘 메 인 파일 입 니 다.    
#include<iostream>
#include"RedBlackNode.h"
using namespace std;

class RedBlackTree
{
private:
	RedBlackNode *Root;
public:
	RedBlackTree();
	RedBlackNode *GetRoot();
	RedBlackNode *FindRB(int );
	void UpdataRBNode(int,int);
	void InsertRBNode(int);
	void InsertFixUp(RedBlackNode *);
	void LeftRotate(RedBlackNode *);
	void RightRotate(RedBlackNode *);
	void DeleteFixUp(RedBlackNode *);
	bool DeleteRBNode(int);
	void DeleteNoOrOneChildNode(RedBlackNode *,RedBlackNode *);
	void PreOrderPrint(RedBlackNode *);
	void InOrderPrint(RedBlackNode *);
	void SufOrderPrint(RedBlackNode *);
	void RotatePrint(RedBlackNode *,int);
};

RedBlackTree::RedBlackTree()
{
	Root=NULL;
}

/**********************************************************
*  : 
*   : 
*  :        
************************************************************/
RedBlackNode *RedBlackTree::GetRoot()
{
	return this->Root;
}

/**********************************************************
*  :    
*   : 
*  :     
************************************************************/
void RedBlackTree::InsertRBNode(int tempKey)
{
	RedBlackNode *pre=NULL,*cur=this->Root;
	while(cur!=NULL)
	{
		pre=cur;
		if(cur->key>tempKey)//tempKey     
			cur=cur->leftChild;
		else cur=cur->rightChild;//     
	}
	RedBlackNode *tempNode=new RedBlackNode(tempKey);
	tempNode->parent=pre;
	if(pre==NULL)//        
	{
		this->Root=tempNode;
	}
	else if(pre->key>tempNode->key)
		pre->leftChild=tempNode;
	else pre->rightChild=tempNode;
	
	InsertFixUp(tempNode);//       
}

/**********************************************************
*  :    
*   :          ,    NULL
*  :     
************************************************************/
RedBlackNode *RedBlackTree::FindRB(int tempKey)
{
	RedBlackNode *cur=this->Root;
	while(cur!=NULL)
	{
		if(cur->key==tempKey)
			break;
		else if(cur->key>tempKey)
			cur=cur->leftChild;
		else cur=cur->rightChild;
	}
	return cur;
}

/**********************************************************
*  :     oldKey,      newKey
*   : 
*  :      
************************************************************/
void RedBlackTree::UpdataRBNode(int oldKey,int newKey)
{
	DeleteRBNode(oldKey);
	InsertRBNode(newKey);
}

/**********************************************************
*  :    
*   : 
*  :  
************************************************************/
void RedBlackTree::LeftRotate(RedBlackNode *tempNode)
{
	RedBlackNode *rChildNode=tempNode->rightChild;
	if(rChildNode->leftChild!=NULL)//          
		rChildNode->leftChild->parent=tempNode;
	rChildNode->parent=tempNode->parent;
	if(NULL==tempNode->parent)//        
		this->Root=rChildNode;
	else if(tempNode==tempNode->parent->leftChild)
		tempNode->parent->leftChild=rChildNode;
	else tempNode->parent->rightChild=rChildNode;
	tempNode->parent=rChildNode;
	tempNode->rightChild=rChildNode->leftChild;
	rChildNode->leftChild=tempNode;
}

/**********************************************************
*  :    
*   : 
*  :  
************************************************************/
void RedBlackTree::RightRotate(RedBlackNode *tempNode)
{
	RedBlackNode *lChildNode=tempNode->leftChild;
	if(lChildNode->rightChild!=NULL)//          
		lChildNode->rightChild->parent=tempNode;
	lChildNode->parent=tempNode->parent;
	if(NULL==tempNode->parent)//        
		this->Root=lChildNode;
	else if(tempNode==tempNode->parent->leftChild)
		tempNode->parent->leftChild=lChildNode;
	else tempNode->parent->rightChild=lChildNode;
	tempNode->parent=lChildNode;
	tempNode->leftChild=lChildNode->rightChild;
	lChildNode->rightChild=tempNode;
}

/**********************************************************
*  :      
*   : 
*  :                 
************************************************************/
void RedBlackTree::InsertFixUp(RedBlackNode *tempNode)
{
	RedBlackNode *parTempNode=tempNode->parent,*ancleTempNode;
	while(parTempNode!=NULL&&RED==parTempNode->color)//          
	{
		if(parTempNode->parent!=NULL)
		{
			if(parTempNode->parent->leftChild==parTempNode)
			{
				ancleTempNode=parTempNode->parent->rightChild;
				if(ancleTempNode!=NULL&&RED==ancleTempNode->color)//       
				{
					parTempNode->color=BLACK;
					ancleTempNode->color=BLACK;
					parTempNode->parent->color=RED;
					tempNode=parTempNode->parent;//      
					parTempNode=tempNode->parent;
				}
				else 
				{
					if(tempNode==parTempNode->rightChild)
					{
						LeftRotate(parTempNode);
						tempNode=tempNode->leftChild;
						parTempNode=tempNode->parent;
					}
					parTempNode->color=BLACK;
					parTempNode->parent->color=RED;
					RightRotate(parTempNode->parent);
					break;
				}
			}
			else 
			{
				ancleTempNode=parTempNode->parent->leftChild;
				if(ancleTempNode!=NULL&&RED==ancleTempNode->color)//       
				{
					parTempNode->color=BLACK;
					ancleTempNode->color=BLACK;
					parTempNode->parent->color=RED;
					tempNode=parTempNode->parent;//      
					parTempNode=tempNode->parent;
				}
				else{
					if(tempNode==parTempNode->leftChild)
					{
						RightRotate(parTempNode);
						tempNode=tempNode->rightChild;
						parTempNode=tempNode->parent;
					}
					parTempNode->color=BLACK;
					parTempNode->parent->color=RED;
					LeftRotate(parTempNode->parent);
					break;
				}
			}
		}
		else break;
	}
	this->Root->color=BLACK;
}

/**********************************************************
*  :pre         ,cur     
*   : 
*  :            
************************************************************/
void RedBlackTree::DeleteNoOrOneChildNode(RedBlackNode *pre,RedBlackNode *cur)
{
	if(NULL==cur->leftChild&&NULL==cur->rightChild)//      
	{
		if(NULL==pre)
			Root=NULL;
		else if(pre->leftChild==cur)
			pre->leftChild=NULL;
		else pre->rightChild=NULL;
		delete cur;
	}
	else if(cur->rightChild!=NULL)//       
	{
		if(NULL==pre)
		{
			Root=cur->rightChild;
			Root->parent=NULL;
		}
		else if(pre->leftChild==cur)
		{
			pre->leftChild=cur->rightChild;
			cur->rightChild->parent=pre;
		}
		else 
		{
			pre->rightChild=cur->rightChild;
			cur->rightChild->parent=pre;
		}
		delete cur;
	}
	else if(cur->leftChild!=NULL)//       
	{
		if(NULL==pre)
		{
			Root=cur->leftChild;
			Root->parent=NULL;
		}
		else if(pre->leftChild==cur)
		{
			pre->leftChild=cur->leftChild;
			cur->leftChild->parent=pre;
		}
		else
		{
			pre->rightChild=cur->leftChild;
			cur->leftChild->parent=pre;
		}
		delete cur;
	}
}

/**********************************************************
*  :       
*   : 
*  :        
************************************************************/
void RedBlackTree::DeleteFixUp(RedBlackNode *tempNode)
{
	if(RED==tempNode->color)
		InsertFixUp(tempNode);
}

/**********************************************************
*  :        
*   : 
*  :      
************************************************************/
bool RedBlackTree::DeleteRBNode(int tempKey)
{
	RedBlackNode *pre=NULL,*cur=Root;
	while(cur!=NULL)//       
	{
		if(cur->key==tempKey)
			break;
		else
		{
			pre=cur;
			if(cur->key>tempKey)
				cur=cur->leftChild;
			else cur=cur->rightChild;
		}
	}
	if(NULL==cur)return false;
	RedBlackNode *tempChild;
	bool tempColor;
	if(NULL==cur->leftChild||NULL==cur->rightChild)
	{
		if(NULL==cur->leftChild)//     
			tempChild=cur->rightChild;
		else tempChild=cur->leftChild;
		tempColor=cur->color;
		DeleteNoOrOneChildNode(pre,cur);
		if(tempChild!=NULL&&BLACK==tempColor)
			DeleteFixUp(tempChild);
	}
	else //        
	{
		RedBlackNode *rPre=cur,*rCur=cur->rightChild;//         
		while(rCur->leftChild!=NULL)
		{
			rPre=rCur;
			rCur=rCur->leftChild;
		}
		cur->key=rCur->key;
		tempChild=rCur->rightChild;//      
		tempColor=rCur->color;
		DeleteNoOrOneChildNode(rPre,rCur);
		if(tempChild!=NULL&&BLACK==tempColor)
			DeleteFixUp(tempChild);
	}
	
}

/**********************************************************
*  :       
*   : 
*  :       
************************************************************/
void RedBlackTree::PreOrderPrint(RedBlackNode *tempRoot)
{
	if(NULL==tempRoot)
		return ;
	cout<<"("<<tempRoot->key<<",";
	if(tempRoot->color)
		cout<<" )  ";
	else cout<<" )  ";
	PreOrderPrint(tempRoot->leftChild);
	PreOrderPrint(tempRoot->rightChild);
}

/**********************************************************
*  :       
*   : 
*  :       
************************************************************/
void RedBlackTree::InOrderPrint(RedBlackNode *tempRoot)
{
	if(NULL==tempRoot)
		return ;
	InOrderPrint(tempRoot->leftChild);
	cout<<"("<<tempRoot->key<<",";
	if(tempRoot->color)
		cout<<" )  ";
	else cout<<" )  ";
	InOrderPrint(tempRoot->rightChild);
}

/**********************************************************
*  :       
*   : 
*  :       
************************************************************/
void RedBlackTree::SufOrderPrint(RedBlackNode *tempRoot)
{
	if(NULL==tempRoot)
		return ;
	SufOrderPrint(tempRoot->leftChild);
	SufOrderPrint(tempRoot->rightChild);
	cout<<"("<<tempRoot->key<<",";
	if(tempRoot->color)
		cout<<" )  ";
	else cout<<" )  ";
}

/**********************************************************
*  :       ,    
*   : 
*  :         
************************************************************/
void RedBlackTree::RotatePrint(RedBlackNode *tempRoot,int tempColumn)
{
	if(NULL==tempRoot)
		return ;
	RotatePrint(tempRoot->leftChild,tempColumn+1);
	for(int i=0;i<tempColumn;i++)
		cout<<"    ";
	cout<<"("<<tempRoot->key<<",";
	if(tempRoot->color)
		cout<<" )";
	else cout<<" )";
	cout<<endl;
	RotatePrint(tempRoot->rightChild,tempColumn+1);
}

int main()
{
	int val;
	while(true)
	{
		RedBlackTree myRedBlackTree;
		while(cin>>val)
		{
			if(val==0)break;
			myRedBlackTree.InsertRBNode(val);
		}
		cout<<endl<<"*****************************"<<endl;
		cout<<endl<<"=============  ============="<<endl;
		myRedBlackTree.PreOrderPrint(myRedBlackTree.GetRoot());
		cout<<endl<<"=============  ============="<<endl;
		myRedBlackTree.InOrderPrint(myRedBlackTree.GetRoot());
		cout<<endl<<"==============  ============="<<endl;
		myRedBlackTree.SufOrderPrint(myRedBlackTree.GetRoot());
		cout<<endl<<"==============  +     ============="<<endl;
		myRedBlackTree.RotatePrint(myRedBlackTree.GetRoot(),0);
		cout<<endl<<"============================="<<endl;
		cout<<"*****************************"<<endl;
		while(cin>>val)
		{
			if(!val)break;
			myRedBlackTree.DeleteRBNode(val);
			cout<<endl<<"*****************************"<<endl;
			cout<<endl<<"=============  ============="<<endl;
			myRedBlackTree.PreOrderPrint(myRedBlackTree.GetRoot());
			cout<<endl<<"=============  ============="<<endl;
			myRedBlackTree.InOrderPrint(myRedBlackTree.GetRoot());
			cout<<endl<<"==============  ============="<<endl;
			myRedBlackTree.SufOrderPrint(myRedBlackTree.GetRoot());
			cout<<endl<<"==============  +     ============="<<endl;
			myRedBlackTree.RotatePrint(myRedBlackTree.GetRoot(),0);
			cout<<endl<<"============================="<<endl;
			cout<<"*****************************"<<endl;
		}
	}
	system("pause");
	return 0;
}

      
  부정 을 환영 합 니 다!

좋은 웹페이지 즐겨찾기