红黑树

来源:互联网 发布:软件项目质量 考题 编辑:程序博客网 时间:2024/06/07 00:53
C++实现红黑树,红黑树的讲解可以参见维基百科,相当仔细,http://zh.wikipedia.org/zh/红黑树,下面是代码。
/*红黑树的结点定义*///红黑树颜色#pragma once#include "RBTree.h"enum rb{RED=0,BLACK};//红黑树结点class Node{friend class RBTree;int value;    //结点值rb color;     Node *lchild,*rchild,*parent;//默认构造函数Node(int va=0,Node* nil=0,rb co=RED):value(va),color(co),lchild(nil),rchild(nil),parent(0){}//返回祖父结点的指针函数Node* grandParent(){if(parent==0)return 0;return parent->parent;}//返回叔父结点的指针Node* uncle(){Node* gParent=grandParent();if(gParent==0)return 0;if(parent==gParent->lchild)return gParent->rchild;elsereturn gParent->lchild;}//返回兄弟结点的指针Node* sibling(){if(parent->lchild==this)return parent->rchild;elsereturn parent->lchild;}//返回结点的颜色//rb col(){return color;}};/*红黑树的类文件,实现红黑树,在节点的插入和删除过程中,保持*红黑树的性质,仅作为红黑树的学习之用*2014.9.14 */#pragma once#include "Node.h"class RBTree{public:RBTree(void):root(0),NIL(new Node(0,0,BLACK)){};~RBTree(void);void insert(int);void deleteVal(int);   //删除关键字结点void display();   //显示红黑树private:Node *root,*NIL;   void rotate_right(Node*);     //右旋转void rotate_left(Node*);      //左旋转void show(Node*);  //递归输出树void destory();    //销毁树void desNode(Node*);  //销毁结点int search(int,Node* &);      //查找红黑树中的元素void insertLoc(Node*,int);     //插入结点void insertCase(Node*);     //调整使仍为红黑树Node* getSmall(Node*);    //获得右子树的最小关键字的结点void swap(Node*,Node*);   //子树替代void deleteNode(Node*);   //删除结点void deleteCase(Node*,rb); //调整使称为红黑树};#include "RBTree.h"#include <iostream>using namespace std;RBTree::~RBTree(void){destory();}void RBTree::rotate_right(Node* n){if(n->parent!=0 && n->parent->lchild==n)n->parent->lchild=n->lchild;else if(n->parent!=0 && n->parent->rchild==n)n->parent->rchild=n->lchild;elseroot=n->lchild;n->lchild->parent=n->parent;n->parent=n->lchild;n->lchild=n->lchild->rchild;if(n->lchild!=NIL)n->lchild->parent=n;n->parent->rchild=n;}void RBTree::rotate_left(Node* n){if(n->parent!=0 && n->parent->lchild==n)n->parent->lchild=n->rchild;else if(n->parent!=0 && n->parent->rchild==n)n->parent->rchild=n->rchild;elseroot=n->rchild;n->rchild->parent=n->parent;n->parent=n->rchild;n->rchild=n->rchild->lchild;if(n->rchild!=NIL)n->rchild->parent=n;n->parent->lchild=n;}void RBTree::display(){if(!root)return;elseshow(root);}void RBTree::show(Node* p){cout<<p->value<<":";if(p->color==RED)cout<<"红";elsecout<<"黑";cout<<"--左";if(p->lchild!=NIL)cout<<p->lchild->value<<"  ";cout<<"右";if(p->rchild!=NIL)cout<<p->rchild->value;cout<<endl;if(p->lchild!=NIL)show(p->lchild);if(p->rchild!=NIL)show(p->rchild);}void RBTree::destory(){if(!root)return;elsedesNode(root);delete NIL;}void RBTree::desNode(Node* p){if(p->lchild!=NIL)desNode(p->lchild);if(p->rchild!=NIL)desNode(p->rchild);cout<<"销毁"<<p->value<<"结点"<<endl;delete p;}//插入值为x的结点void RBTree::insert(int x){if(!root)root=new Node(x,NIL,BLACK);else{Node* p=0;if(search(x,p)==0)return;elseinsertLoc(p,x);}}//查找元素函数int RBTree::search(int x,Node* &p){//在以root为根的红黑树中查找关键字为x的元素,如果查找成功,返回0,p指向//查找到的元素的位置,否则返回1,p指向做比较的最后一个元素if(!root)return 1;p=root;while(p->value!=x){if(p->value>x && p->lchild!=NIL)p=p->lchild;else if(p->value<x && p->rchild!=NIL)p=p->rchild;elsereturn 1;}return 0;}void RBTree::insertLoc(Node* p,int x){//以p结点为父节点插入关键字为x的结点Node *r=new Node(x,NIL);r->parent=p;if(p->value>x)p->lchild=r;elsep->rchild=r;insertCase(r);}void RBTree::insertCase(Node* p){//插入一个结点后,如果不满足红黑树的条件,调整之if(p->parent==0)p->color=BLACK;else if(p->parent->color==BLACK)return;else if(p->uncle()->color==RED){p->parent->color=BLACK;p->uncle()->color=BLACK;p->grandParent()->color=RED;insertCase(p->grandParent());}else if(p==p->parent->rchild && p->parent==p->grandParent()->lchild){rotate_left(p->parent);p->color=BLACK;p->parent->color=RED;rotate_right(p->parent);}else if(p==p->parent->lchild && p->parent==p->grandParent()->rchild){rotate_right(p->parent);p->color=BLACK;p->parent->color=RED;rotate_left(p->parent);}else if(p==p->parent->lchild && p->parent==p->grandParent()->lchild){p->parent->color=BLACK;p->grandParent()->color=RED;rotate_right(p->grandParent());}else{p->parent->color=BLACK;p->grandParent()->color=RED;rotate_left(p->grandParent());}}Node* RBTree::getSmall(Node* p){Node* r=p->rchild;while(r->lchild!=NIL)r=r->lchild;return r;}void RBTree::swap(Node* ori,Node* re){//将re子树嫁接到ori原来的位置上if(ori->parent==0){//ori为根结点root=re;re->parent=0;}else{re->parent=ori->parent;if(ori==ori->parent->lchild)ori->parent->lchild=re;elseori->parent->rchild=re;}}void RBTree::deleteVal(int x){Node* p=0;if(search(x,p)==1)return;elsedeleteNode(p);}void RBTree::deleteNode(Node* n){Node *p=n,*r;if(p->lchild==NIL)r=p->rchild;else if(p->rchild==NIL)r=p->lchild;else{p=getSmall(p);r=p->rchild;n->value=p->value;}rb col=p->color;swap(p,r);delete p;deleteCase(r,col);}void RBTree::deleteCase(Node* n,rb col){if(col==RED)return;else{if(n->color==RED)n->color=BLACK;else if(n->parent!=0){Node* sb=n->sibling();if(sb->color==RED){n->parent->color=RED;sb->color=BLACK;if(n==n->parent->lchild)rotate_left(n->parent);elserotate_right(n->parent);deleteCase(n,BLACK);}else if(n->parent->color==BLACK && sb->lchild->color==BLACK && sb->rchild->color==BLACK){sb->color=RED;deleteCase(n->parent,BLACK);}else if(n->parent->color==RED && sb->lchild->color==BLACK && sb->rchild->color==BLACK){sb->color=RED;n->parent->color=BLACK;}else if(n==n->parent->lchild && sb->rchild->color==BLACK){sb->color=RED;sb->lchild->color=BLACK;rotate_right(sb);//旋转后,找出新的兄弟结点sb=n->sibling();sb->color=n->parent->color;n->parent->color=BLACK;sb->rchild->color=BLACK;rotate_left(n->parent);}else if(n==n->parent->rchild && sb->lchild->color==BLACK){sb->color=RED;sb->rchild->color=BLACK;rotate_left(sb);sb->color=n->parent->color;n->parent->color=BLACK;sb->lchild->color=BLACK;rotate_right(n->parent);}else{sb->color==n->parent->color;n->parent->color=BLACK;if(n==n->parent->lchild){sb->rchild->color=BLACK;rotate_left(n->parent);}else{sb->lchild->color=BLACK;rotate_right(n->parent);}}}else;}if(root==NIL)root=0;}#include <iostream>#include "RBTree.h"int main(void){RBTree tree;tree.insert(5);int arry[8]={4,6,5,7,2,9,3,8,};for(int i=0;i<8;++i)tree.insert(arry[i]);//tree.display();std::cout<<std::endl<<std::endl;for(int i=0;i<8;++i)tree.deleteVal(arry[i]);std::cout<<std::endl;tree.display();for(int i=0;i<8;++i)tree.insert(arry[i]);tree.display();for(int i=0;i<8;++i)tree.deleteVal(arry[i]);std::cout<<std::endl;tree.display();int a[20]={12,4,6,1,2,8,7,6,3,4,7,13,10,14,16,15,6,4,5,9};for(int i=0;i<20;++i)tree.insert(a[i]);tree.deleteVal(6);tree.display();system("pause");return 0;}

0 0
原创粉丝点击