红黑树
来源:互联网 发布:兼容mac的游戏 编辑:程序博客网 时间:2024/04/29 14:06
【红黑树的性质】
红黑树是一种特殊的二叉查找树,红黑树的所有空指针用外部节点nullNode(nullNode->rchild=nullNode->rchild=nullNode)代替。红黑树具有以下性质:
- 根节点是黑色的
- 所有节点不是黑色就是红色
- 外部节点都是黑色的
- 红色节点的孩子节点一定是黑色的
- 所有从根节点到外部节点的所有路径上,包含相同数目的黑色节点。
【代码实现】
// redblacktree.h代码#ifndef redblacktree_h#define redblacktree_htemplate <class T> class RedblackTree;template <class T>class Node{friend class RedblackTree<T>;//private:public: T data; Node<T> *rchild; Node<T> *lchild; int color;};template <class T>class RedblackTree{ public: RedblackTree(const T negInf); //利用构造函数初始化伪根 ~RedblackTree(); //利用析构函数释放空间 void reclaimMemory(Node<T> *p); enum{black,red}; void insert(T item); //插入操作 void handleReorient(T item); //调整操作 Node<T> *rotate(T item,Node<T> *parent);//旋转 void rotationwithLeft(Node<T> *&k2); void rotationwithRight(Node<T> *&k1); void preorder(); //前序遍历 void preorder(Node<T> *currentnode); void findMin(); //查找最小值 void findMax(); //查找最大值private: Node<T> *header; //伪根 Node<T> *nullNode; //空节点 Node<T> *current; Node<T> *parent; //父节点 Node<T> *grand; //祖父节点 Node<T> *great; //曾祖父节点};template<class T>RedblackTree<T>::RedblackTree(const T negInf){ nullNode=new Node<T>(); nullNode->rchild=nullNode; nullNode->lchild=nullNode; header=new Node<T>(); header->data=negInf; header->color=black; header->rchild=nullNode; header->lchild=nullNode;}template<class T>RedblackTree<T>::~RedblackTree(){ reclaimMemory(header->rchild); delete header; delete nullNode;}template<class T>void RedblackTree<T>::insert(T item){ current=parent=grand=header; nullNode->data=item; //----插入数据到二叉查找树中----- while(current->data!=item) { great=grand; grand=parent; parent=current; //parent为插入位置 if(item<current->data) { current=current->lchild; } else { current=current->rchild; } if(current->lchild->color==red&¤t->rchild->color==red) { handleReorient(item); //处理有两个红色孩子的节点 } } if(current!=nullNode) throw "不能插入重复的数据"; current=new Node<T>(); current->data=item; current->lchild=nullNode; current->rchild=nullNode; if(item<parent->data) parent->lchild=current; else parent->rchild=current; handleReorient(item); //插入节点后,处理父亲节点也是红色的情况}//------------单旋转(情况1)------------template<class T>void RedblackTree<T>::rotationwithLeft(Node<T> *&k2){ Node<T> *k1=k2->lchild; k2->lchild=k1->rchild; k1->rchild=k2; k2=k1;}//------------单旋转(情况2)------------template<class T>void RedblackTree<T>::rotationwithRight(Node<T> *&k1){ Node<T> *k2=k1->rchild; k1->rchild=k2->lchild; k2->lchild=k1; k1=k2;}//--------------旋转情况的判断---------------template<class T>Node<T> *RedblackTree<T>::rotate(T item,Node<T> *theParent){ if(item<theParent->data) { item<theParent->lchild->data? rotationwithLeft(theParent->lchild): rotationwithRight(theParent->lchild); return theParent->lchild; } else { item<theParent->rchild->data? rotationwithLeft(theParent->rchild): rotationwithRight(theParent->rchild); return theParent->rchild; }}//-----------调整操作--------------template<class T>void RedblackTree<T>::handleReorient(T item){ //变色 current->color=red; current->lchild->color=black; current->rchild->color=black; //旋转 if(parent->color==red) //此时出现两个连续的红色节点(父亲节点跟插入节点都是红色的) { grand->color=red; if(item<grand->data==item<parent->data)//这种情况即单旋转 { } else //这种情况即双旋转(两次旋转操作) { parent=rotate(item,grand); } current=rotate(item,great); current->color=black; } header->rchild->color=black; //根节点一定是黑的}//--------递归实现前序遍历---------template<class T>void RedblackTree<T>::preorder(){ cout<<"前序遍历为:"; preorder(header->rchild); cout<<endl;}template<class T>void RedblackTree<T>::preorder(Node<T> *currentnode){ if(currentnode!=nullNode) { cout<<currentnode->data<<" "; preorder(currentnode->lchild); preorder(currentnode->rchild); }}//---------------释放空间----------template<class T>void RedblackTree<T>::reclaimMemory(Node<T> *p){ if(p!=nullNode) { reclaimMemory(p->lchild); reclaimMemory(p->rchild); delete p; } }//-----------查找最小值---------template<class T>void RedblackTree<T>::findMin(){ Node<T> *p=header->rchild; if(p==nullNode) { cout<<"这是一棵空树"<<endl; } else { while(p->lchild!=nullNode) { p=p->lchild; } cout<<"最小值为:"<<p->data<<endl; }}//-----------查找最大值---------template<class T>void RedblackTree<T>::findMax(){ Node<T> *p=header->rchild; if(p==nullNode) { cout<<"这是一棵空树"<<endl; } else { while(p->rchild!=nullNode) { p=p->rchild; } cout<<"最大值为:"<<p->data<<endl; }}#endif
// main.cpp代码#include"redblacktree.h"#include<iostream>using namespace std;int main(){const int a=-188999; //伪根数据RedblackTree<int> RB1(a);RB1.insert(50);RB1.insert(10);RB1.insert(80);RB1.insert(90);RB1.insert(70);RB1.insert(60);RB1.insert(65);RB1.insert(62);RB1.preorder();RB1.findMin();RB1.findMax();cout<<"ok!"<<endl;system("pause");return 0;}
【结果】
插入数据后的红黑树如下:
程序运行结果:
0 0
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 优化的原则
- ImageView图片自适应
- 1006. 换个格式输出整数 (15)
- 解答:一个交换机内部的mac表的表项的个数
- 【实例变量创建与实现】
- 红黑树
- 1007. 素数对猜想 (20)
- MongoDB初探系列之一:MongoDB安装及建议配置
- POJ 3159 Candies(差分约束 转spfa+stack 求最短路径)
- PHP底层的运行机制与原理
- 从Eclipse迁移代码到Android Studio可能出现的异常
- 线性表链式存储设计与实现 - API实现
- 1008. 数组元素循环右移问题 (20)
- [LeetCode]4Sum