为了检验红黑树的正确性,这里的输入数组为 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;
- }