您的位置:首页 > 其它

算法练习五 红黑树上 实现了左旋转、右旋转、以及插入

2011-05-01 20:09 549 查看
为了检验红黑树的正确性,这里的输入数组为 41 67 34 0 69 24 78 58 62 64

最后的输出结果为:

62 黑

L[62] = 41 红

R[62] = 69 红

L[41] = 24 黑

R[41] = 58 黑

L[69] = 67 黑

R[69] = 79 黑

L[24] = 0 红

R[24] = 34 红

红黑树的节点

#pragma once
#define RED 1
#define BLACK 2
class RBNode{
public:
RBNode();
public:
int key;
RBNode* pParent;
RBNode* pLeft;
RBNode* pRight;
int color;
};
//左旋转
void LeftRotate(RBNode** proot, RBNode* x, RBNode* pguardNode);
//右旋转
void RightRotate(RBNode** root, RBNode* x, RBNode* pguardNode);
//插入
void RBInsert(RBNode** proot,RBNode* pnode, RBNode* pguardNode);
//插入修正
void RBInsertFixup(RBNode** proot, RBNode* x, RBNode* pguardNode);
//中序遍历
void InorderTreeWalk(RBNode* proot, RBNode* pguardNode);
//采用中序遍历递归的方法在树中寻找一个元素
void FindNodeInBSTree(RBNode* proot, int key, RBNode** pnode,RBNode* pguardNode);


主要函数实现

// RBTRee.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "rbnode.h"
#include<iostream>
#include<stdlib.h>
#include<time.h>
#include<queue>
using namespace std;
#define random(x) (rand()%x)
//一层一层遍历其中的元素
void LayerOrder(RBNode* proot,RBNode* pguardNode);
// The Main Method
int _tmain(int argc, _TCHAR* argv[])
{
int num = 10;
cout << "请输入需要排序数组的长度,数组将随机生成:" <<endl;
cin >> num;
int* ary =  new int[num];
//srand( (int)time( 0 ) );
for ( int x=0; x<num; x++ )
{
ary[x] = random(100);
cout << ary[x] << endl;
}
//先生成一个不一定符合规则的红黑树,试试与二叉查找树相比修改后的插入方法是否正确
RBNode* proot = NULL;
RBNode* pguardNode = new RBNode();
pguardNode->key = 111;
pguardNode->color = BLACK;

for ( int x=0; x<num; x++)
{
RBNode* pnode = new RBNode();
pnode->key = ary[x];
RBInsert( &proot, pnode, pguardNode );
}
//逐层输出
cout << "逐层输出" << endl;
LayerOrder( proot, pguardNode );
//中序遍历输出
/*cout << "中序遍历" << endl;
InorderTreeWalk( proot, pguardNode );*/

//int nkey;
//cout << "选择一个数" << endl;
//cin >> nkey;
//RBNode* pfindNode = NULL;
//FindNodeInBSTree( proot, nkey, &pfindNode,pguardNode);
//int LorR;
//cout << "左旋转输入1,右旋转输入2" << endl;
//cin >> LorR;
//if ( LorR == 1 )
//{
//	LeftRotate( &proot, pfindNode, pguardNode );
//}
//else
//{
//	RightRotate( &proot, pfindNode, pguardNode );
//}
//cout << "旋转完成" << endl;
////InorderTreeWalk( proot, pguardNode );
//LayerOrder( proot, pguardNode );
system("pause");
delete[] ary;
return 0;
}

//
void LayerOrder(RBNode* proot,RBNode* pguardNode)
{
//借用队列进行输出
std::queue<RBNode*> rbQueue;
rbQueue.push( proot );
while ( !rbQueue.empty() )
{
RBNode* p = rbQueue.front();
rbQueue.pop();
if ( p->pLeft != pguardNode )
{
rbQueue.push( p->pLeft );
}
if ( p->pRight != pguardNode )
{
rbQueue.push( p->pRight );
}
cout << "key=" << p->key << "color=" << p->color << endl;
}

}
//左旋转
void LeftRotate(RBNode** proot, RBNode* px, RBNode* pguardNode)
{
//叶子节点不存在左旋还是右旋
if ( px->pLeft == pguardNode && px->pRight == pguardNode )
{
return;
}
RBNode* y = px->pRight;  //向左旋转,需要找到px的右子树

//将原先px的右子树修改指向y的左子树
px->pRight = y->pLeft;
if ( y->pLeft != pguardNode )
{
y->pLeft->pParent = px;	//将y的左子树的父指针指向px
}
//修改px的父节点与px的联系,将y的父节点指向px,然后将px的父节点的子树指针指向y
y->pParent = px->pParent;
if ( px->pParent == pguardNode )
{
*proot = y;
}
else
{
if ( px == px->pParent->pLeft )
{
px->pParent->pLeft  = y;
}
else
{
px->pParent->pRight = y;
}
}

//重新建立px 与 y的子父关系
y->pLeft = px;
px->pParent = y;
}
//右旋转
void RightRotate(RBNode** proot, RBNode* px, RBNode* pguardNode)
{
RBNode* y = px->pLeft;
//修改y的右子树
px->pLeft = y->pRight;
if ( y->pRight != pguardNode )
{
y->pRight->pParent = px;
}
//修改px的父指针
y->pParent = px->pParent;
if ( px->pParent == pguardNode )
{
*proot = y;
}
else
{
if ( px == px->pParent->pLeft )
{
px->pParent->pLeft = y;
}
else
{
px->pParent->pRight = y;
}
}
//重新建立px与y的子父关系
y->pRight = px;
px->pParent = y;
}
//中序遍历
void InorderTreeWalk(RBNode* proot, RBNode* pguardNode)
{
if ( proot != pguardNode && proot != NULL)
{
InorderTreeWalk( proot->pLeft, pguardNode );
cout << "key=" << proot->key << "/t" << "color=";
proot->color == RED ? cout << "red" : cout << "black";
cout << endl;
InorderTreeWalk( proot->pRight, pguardNode );
}
}
//采用中序遍历递归的方法在树中寻找一个元素
void FindNodeInBSTree(RBNode* x, int key, RBNode** pnode,RBNode* pguardNode)
{
if ( x != NULL && *pnode == NULL && x != pguardNode  )
{

//cout << "In Left"<< endl;
FindNodeInBSTree( x->pLeft, key, pnode,pguardNode);
//cout << "Out Left"<< endl;

//cout << x->key << endl;
if ( x->key == key )
{
*pnode = x;
//cout << "===========" << x->key << "============" << endl;
return;
}

//cout << "In Right"<< endl;
FindNodeInBSTree( x->pRight, key, pnode, pguardNode);
//cout << "Out Right"<< endl;
}
}
//插入
void RBInsert(RBNode** proot,RBNode* pnode, RBNode* pguardNode)
{
RBNode* y = pguardNode;
RBNode* x = *proot;
while ( x != pguardNode && x!= NULL )
{
y = x;
if ( pnode->key < x->key)
{
x = x->pLeft;
}
else
{
x = x->pRight;
}
}
pnode->pParent = y;
if ( y == pguardNode )
{
*proot = pnode;
}
else
{
if ( pnode->key < y->key )
{
y->pLeft = pnode;
}
else
{
y->pRight = pnode;
}
}
pnode->pLeft = pguardNode;
pnode->pRight = pguardNode;
pnode->color = RED;
RBInsertFixup( proot, pnode, pguardNode );
}
//插入修正
void RBInsertFixup(RBNode** proot, RBNode* x, RBNode* pguardNode)
{
while ( x->pParent->color == RED )
{
//x的父节点 == x的祖父节点的左子树
if ( x->pParent == x->pParent->pParent->pLeft )
{
RBNode* y = x->pParent->pParent->pRight;
if ( y->color == RED )
{
x->pParent->color = BLACK;
y->color = BLACK;
x->pParent->pParent->color = RED;
x = x->pParent->pParent;
}
else
{
if ( x == x->pParent->pRight )
{
x = x->pParent;
LeftRotate(proot,x,pguardNode);
}
x->pParent->color = BLACK;
x->pParent->pParent->color = RED;
RightRotate(proot,x->pParent->pParent, pguardNode);
}
}//end if x的父节点 == x的祖父节点的左子树
else// else x的父节点 == x的祖父节点的右子树
{
RBNode* y = x->pParent->pParent->pLeft;
if ( y->color == RED )
{
x->pParent->color = BLACK;
y->color = BLACK;
x->pParent->pParent->color = RED;
x = x->pParent->pParent;
}
else
{
if ( x == x->pParent->pLeft )
{
x = x->pParent;
RightRotate(proot,x,pguardNode);
}
x->pParent->color = BLACK;
x->pParent->pParent->color = RED;
LeftRotate(proot,x->pParent->pParent, pguardNode);
}

}
}//end while loop
(*proot)->color = BLACK;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: