红黑树

【红黑树的性质】

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

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

【代码实现】

//  redblacktree.h代码
#ifndef redblacktree_h
#define redblacktree_h
template <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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值