红黑树

来源:互联网 发布:兼容mac的游戏 编辑:程序博客网 时间:2024/04/29 14:06

【红黑树的性质】

红黑树是一种特殊的二叉查找树,红黑树的所有空指针用外部节点nullNode(nullNode->rchild=nullNode->rchild=nullNode)代替。红黑树具有以下性质:

  1. 根节点是黑色的
  2. 所有节点不是黑色就是红色
  3. 外部节点都是黑色的
  4. 红色节点的孩子节点一定是黑色的
  5. 所有从根节点到外部节点的所有路径上,包含相同数目的黑色节点。

【代码实现】

//  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&&current->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