算法练习五 红黑树上 实现了左旋转、右旋转、以及插入
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 红
红黑树的节点
主要函数实现
最后的输出结果为:
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; }
相关文章推荐
- [算法练习]插入排序的C语言实现
- 读取一串整数,寻找合适的数据结构和算法,实现插入元素track(int x) 方法,以及GetRankOfNumber(int x)方法,返回值为小于等于x的元素个数(不包括x本身)
- 求旋转数组的最小数字算法的解析以及完整c语言代码实现
- 算法练习--二分搜索哈希表-JS 实现
- 白话经典算法系列之二 直接插入排序的三种实现
- C++实现数组的排序/插入重新排序/以及逆置操作
- php实现弗吉尼亚算法加密解密以及重合指数分析
- 经典算法:红黑树的C语言实现 ( 插入 、删除 )
- 用android来实现图片的绘制以及旋转缩放案例分析
- 针对android&ios yuv旋转、镜像、格式转换、裁剪 算法实现
- 图解算法练习--快速排序(GO实现)
- 回首Java——八大排序以及冒泡排序,插入排序分析实现
- KNN算法以及R语言的实现
- Clojure:算法练习的实现(一)——合并排序
- OpenCV中图像旋转(warpAffine)算法的实现过程
- 栈的定义和存储以及算法实现
- 白话经典算法系列之二 直接插入排序的三种实现
- 编写算法实现建立一个带头结点的含n个元素的双向循环链表H,并在链表H中的第i个位置插入一个元素e
- 顺序表创建以及查找排序算法(含有顺序查找算法、带哨兵站顺序查找、折半查找算法、冒泡排序)的C++实现在vs2013环境下实现
- PhotoShop算法实现--图像旋转(十九)