在查找中,虽然hash表查找非常迅速,但是随着数据的种类增多,
hash表长会变得更长,且冲突也会越来越多,那么如何能实现无论在
多大数据量的情况下,查找依然是高性能的呢?

   在1978年,Leo J.Guibas 与 Robert Sedgewick写了一篇论文中
谈到了一种较好的用于查找的数据结构----红黑树

一般来说,树是很好的一种数据结构,那用于插入,删除,查找等
都是很高效的数据树构,但问题是在很坏的情况下,操作很费时间,它的
性能得到不保证,比如二叉查找树中如果左子树与右子树相差太远,那么查找
时就很费时间。这时为了保证其有高效性,就得保证左树与右树不能差得太远,
当向树中插入时,就按一定规则调整,使其达到规则,从而使其整体与局部
查找效率得到提高。这就是红黑树的规则.

   这些规则是
在二叉查找树的基础上,
(1)节点都有颜色,要么黑色,要么红色。
(2)根结点是黑色的,叶子结点是黑色的。
(3)每条从树到叶子的路上没有二个连续的红色。即红色的子树一定是黑色
(4)各条从叶子到根的路上的黑色结点相同。

关键的是(3), (4)它使得树是局部是平衡的,并且每条路线不会太长。

   还有一个重要的点就是,为了研究方便,会在红黑树补成两个子树是完整的,
它们也有颜色,是黑色,但是没有数据,它称为nil叶子,null叶子。当搜索时
发现结点与nil叶子相 等时,则是找到了叶子了。

  另外,关于红黑树与平衡二叉树的区别,它们的区别在概念上也有,
但是在性能上也有,平衡二叉树也是在最坏的情况下有高效的,但是它
追求整体的平衡,使得调整树时,会要很长的时间复杂度,而红黑树是
局部平衡,调整时只要0(logn)颜色变量,并且调整不超过三次。

那么如何使用红黑树来解决问题呢,可以先构造红黑树
构造红黑树的办法如下:
(1)定义节点结构,
一般是 值,key, 长度,左指针,右指针,指向父的指针,颜色。

(2)插入
 插入时,先从树根开始,先校验树是不是为空节点或者nil结点,若是
则插入结点为新根,若不是,则与树比较,小于的话,往左移,大于
往右移,这里与二叉查找树类似,最后再对其颜色进行调整.所谓的调
整只有4种情况,都设计好了。

(3)查找
按照二叉查找树的样子进行查找。

例子:查找班上姓名为'xiaoming'同学的基本信息情况
 办法: 则要以姓名为关键字建立一个红黑树,建法很多,
可以以其各字母ascii和的办法作为关键字,或以某函数生成一个均可。
   然后树据关键字的值生成红黑树,再查找就可以了

部分MFC代码如下:

节点结构。
typedef struct Node
{

Coulor color;
 int key;
 Node *p,*left,*right;
 int size;
 char *name;               //the description data that the  node contained

}Node,*pNode;

下面的代码中,rbInsert(pNode z)为插入创建的函数,
   void rbInsertFixUp(pNode z)为调整局部色彩的函数。

------------------
//RBTree.h文件如下

#ifndef RBTREE_H
#define RBTREE_H

#pragma once

#include
#include"MainFrm.h"

enum Coulor{RED,BLACK};
typedef struct Node
{

Coulor color;
 int key;
 Node *p,*left,*right;
 int size;
 char *name;               //the description data that the  node contained

}Node,*pNode;

extern Node Nil;  //ÉÚ±ø
extern const pNode nil;
class rbTree
{
public:
 pNode root;
    pNode  cur;
public:
 rbTree(){root=cur=&Nil;};
 
 void setName(pNode x,const char*na)
 {
   x->name=new char[strlen(na)+1];
   strcpy(x->name,na);
 }

pNode newNode(int k,const char*na="N",pNode pa=nil,pNode le=nil,pNode ri=nil)
 {
  pNode ne=new Node;
  ne->key=k;
  ne->color=RED;
  ne->left=le;
  ne->p=pa;
  ne->right=ri;
  ne->size=1;
  setName(ne,na);
  return ne;
 }
 
 //·ÃÎÊp,left,rightµÈ
 pNode &p(pNode x){return x->p;};
 pNode &left(pNode x){return x->left;};
 pNode &right(pNode x){return x->right;};
    int   &size(pNode x){return x->size;};
 Coulor &color(pNode x){return x->color;};
 int   &key(pNode x){return x->key;};

//
 const pNode  P(pNode x){return x->p;};
 const pNode  Left(pNode x){return x->left;};
 const pNode  Right(pNode x){return x->right;};
    const int    Size(pNode x){return x->size;};
 const Coulor Color(pNode x){return x->color;};
 const int    Key(pNode x){return x->key;};

pNode successor(pNode x)
 {
  if(Right(x) != nil)
   return minimum(Right(x));
  pNode y= P(x);
  while ( y!=nil && x==Right(y) )
  {
   x=y;
   y=P(y);
  }
  return y;
 }
 //
 pNode minimum( pNode x)
 {
  while (Left(x)!=nil)
   x=Left(x);
  return x;
 }
 
 int Bheight(pNode x)
 {
  pNode y=x;
  int k=0;
  while(y!=nil)
  {
   if(Color(y)==BLACK)
    k++;
   y=Left(y);
  }
  return k;
 }
 
 //×óÐýת
   void lrotate(pNode x)
   {
    pNode y=Right(x);
    //ά»¤size;
    int sx=x->size;
    int sy=y->size;
    size(y)=sx;
    size(x)=sx-size(Right(y))-1;

right(x)=Left(y);
    p(Left(y))=x;
    p(y)=P(x);
    if(P(x)==nil)
    {
     root=y;
    }
    else if( x == Left(P(x)) )
    {
     left(P(y))=y;
    }
    else
     right(P(x))=y;
       left(y)=x;
    p(x)=y;
   }
   //ÓÒÐýת
   void rrotate(pNode x)
   {
    pNode y=Left(x);
   
    //ά»¤size;
   
    size(y)=Size(x);
    size(x)=Size(x)-Size(Left(y))-1;

left(x)=Right(y);
    p(Right(y))=x;
    p(y)=P(x);
    if(P(x)==nil)
    {
     root=y;
    }
    else if(x==Left(P(x)))
    {
     left(P(y))=y;
    }
    else
     right(P(x))=y;
       right(y)=x;
    p(x)=y;
   }
   ///
   //²åÈë¼°Æäµ÷Õû
   //²åÈë
   void rbInsert(pNode z)
   {
    pNode y=nil;
    pNode x=root;

while(x!=nil)
    {
     y=x;
     size(x)=Size(x)+1;
     if(Key(z) < Key(x))
      x=Left(x);
     else
      x=Right(x);
    }
    p(z)=y;
    if(y == nil)
     root=z;
    else if(Key(z)
     left(y)=z;
    else
     right(y)=z;
    rbInsertFixUp(z);

}
   //µ÷Õû
   void rbInsertFixUp(pNode z)
   {
    while(Color(P(z)) == RED)
    {
     if( P(z) == Left(P(P(z))))
     {
      pNode y=Right(P(P(z)));
         if(Color(y) == RED)
      {
       color(P(z)) = BLACK;
       color(y)= BLACK;
       color(P(P(z))) =RED;
       z=P(P(z));
      }
      else
      {
       if(z == Right(P(z)))
       {
        z=P(z);
           lrotate(z);
       }
       color(P(z))=BLACK;
       color(P(P(z)))=RED;
       rrotate(p(P(z)));
      }
     }
     else
     {
      pNode y=Left(P(P(z)));
         if(Color(y) == RED)
      {
       color(P(z)) = BLACK;
       color(y)= BLACK;
       color(P(P(z))) =RED;
       z=P(P(z));
      }
      else
      {
       if(z == Left(P(z)))
       {
        z=P(z);
           rrotate(z);
       }
       color(P(z))=BLACK;
       color(P(P(z)))=RED;
       lrotate(p(P(z)));
      }
     }
    }
      color(root)=BLACK;

}
   //
   //ɾ³ý¼°Æäµ÷Õû
   //ɾ³ý
   pNode rbDelete(pNode z)
   {
    pNode x,y;
    if(Left(z) == nil ||Right(z)==nil)
     y=z;
    else
     y=successor(z);
    if(Left(y) !=nil)
      x=Left(y);
    else
     x=Right(y);
    p(x)=P(y);

if(P(y) ==nil)
     root=x;
    else if(y==Left(P(y)) )
     left(P(y))=x;
       else
     right(P(y))=x;
    if(y!=z)
    {
     key(z)=Key(y);//
    }
       rbDeleteMaitainSize(y);
    if(Color(y)==BLACK)
     rbDeleteFixUp(x);
    return y;

}
   //µ÷Õû
   void rbDeleteFixUp(pNode x)
   {
    while(x!=root && Color(x)==BLACK)
    {
     if(x ==Left(P(x)) )
     {
      pNode w=Right(P(x));
      //case1
               if(Color(w)==RED)
      {
       color(w)=BLACK;
       color(P(x))=RED;
       lrotate(P(x));
       w=Right(P(x));
      }

//case 2,3,4
      if(Color(Left(w))==BLACK && Color(Right(w)) ==BLACK)
      {
       color(w)=RED;
       x=P(x);
      }
      else if(Color(Right(w)) == BLACK)
      {
       color(Left(w))=BLACK;
       color(w)=RED;
       rrotate(w);
       w=Right(P(x));
      }
      else
      {
       color(w)=Color(P(x));
       color(P(x))=BLACK;
       lrotate(P(x));
       x=root;
      }
     }
     else
      {
      pNode w=Left(P(x));
      //case1
               if(Color(w)==RED)
      {
       color(P(x))=RED;
       rrotate(P(x));
       w=Left(P(x));
      }

//case 2,3,4
      if(Color(Left(w))==BLACK && Color(Right(w)) ==BLACK)
      {
       color(w)=RED;
       x=P(x);
      }
      else if(Color(Left(w)) == BLACK)
      {
       color(Right(w))=BLACK;
       color(w)=RED;
       lrotate(w);
       w=Left(P(x));
      }
      else
      {
       color(w)=Color(P(x));
       color(P(x))=BLACK;
       rrotate(P(x));
       x=root;
      }
     }  
    }
    color(x)=BLACK;
   }
   /
   //ά»¤size
   void rbDeleteMaitainSize(pNode x)
   {
    cur=P(x);
    while(cur!=nil)
    {
     size(cur)--;
     cur=P(cur);
    }
   }
   int Rank(pNode x)
   {
    int r= Size(Left(x))+1;
    pNode y=x;
    while(y!=root)
    {
     if(   y  == Right( P(y) )    )
     {
      r=r+Size(Left( P(y) ) )+1;
     }
     y=P(y);
    }
    return r;
   }
 
   pNode OS_Select(pNode x,int i)
   {
    if(i>Size(x))
     return nil;

int r=Size(Left(x))+1;
    if(i==r)
     return x;
    else if(i
     return  OS_Select(Left(x),i);
    else
     return  OS_Select(Right(x),i-r);
   }

friend class CMyWnd;//ÏÔʾºìºÚÊ÷µÄͼÐνçÃæÀࣻ
};

#endif

创建红黑树解决实际问题相关推荐

  1. 红黑树解决了什么问题

    /*** 平衡二叉树:就是为了防止二叉搜索树变为线性数据结构,而出现的数据结构* 而AVL树-绝对平衡树.左右子树的高度差不能超过1* 红黑树:特性:* 1.每个结点不是红色就是黑色* 2.根节点:一 ...

  2. 红黑树探险:从理论到实践,一站式掌握C++红黑树

    红黑树揭秘:从理论到实践,一站式掌握C++红黑树 引言 为什么需要了解红黑树? 红黑树在现代C++编程中的应用场景 树与平衡二叉搜索树 树的基本概念: 二叉搜索树的定义与性质: 平衡二叉搜索树的特点与 ...

  3. 死磕Java并:J.U.C之ConcurrentHashMap红黑树转换分析

    作者:chessy 来源:Java技术驿站 在[死磕Java并发]-----J.U.C之Java并发容器:ConcurrentHashMap一文中详细阐述了ConcurrentHashMap的实现过程 ...

  4. ConcurrentHashMap的红黑树实现分析

    转载自 ConcurrentHashMap的红黑树实现分析 红黑树 红黑树是一种特殊的二叉树,主要用它存储有序的数据,提供高效的数据检索,时间复杂度为O(lgn),每个节点都有一个标识位表示颜色,红色 ...

  5. 算法原理系列:红黑树

    红黑树 看了网上关于红黑树的大量教程,发现一个共性,给出定义,适用情况,然后大量篇幅开始讨论它如何旋转,这就一发不可收拾了,各种情况的讨论,插入删除,插入删除,看的云里雾里,好不容易搞清楚,过段时间就 ...

  6. ConcurrentHashMap的红黑树

    红黑树 红黑树是一种特殊的二叉树,主要用它存储有序的数据,提供高效的数据检索,时间复杂度为O(lgn), 每个节点都有一个标识位表示颜色,红色或黑色,有如下5种特性: 1.每个节点要么红色,要么是黑色 ...

  7. 关于二叉树、平衡二叉树、红黑树

    目录 1.二叉树缺点 2.平衡二叉树 3.为什么有了平衡二叉树,还要红黑树? 参考文章:记一次腾讯面试:有了二叉查找树.平衡树(AVL)为啥还需要红黑树? 1.二叉树缺点 二叉查找树,相信大家都接触过 ...

  8. ConcurrentHashMap 红黑树转换分析

    ConcurrentHashMap 红黑树转换分析 先看红黑树的基本概念:红黑树是一课特殊的平衡二叉树,主要用它存储有序的数据,提供高效的数据检索,时间复杂度为O(lgn).红黑树每个节点都有一个标识 ...

  9. 数据结构与算法 / 红黑树

    一.定义 根节点是黑色的. 叶子节点是空的且是黑色的. 任何相邻的节点不能都为红色. 任意节点到其每个叶子节点的路径上,黑色的节点的数量相同. 二.性质 红黑树解决了 AVL 树增.删时耗时过大的问题 ...

最新文章

  1. linux vim模板,FreeBSD8下的vim配置模板
  2. 如何在eclipse中修改jsp默认编码
  3. 监控mysql主从复制监控_shell脚本监控mysql主从同步状态
  4. 与 python 交互
  5. RS 纠删码为什么可以提高分布式存储可靠性?| 原力计划
  6. TypeError: unorderable types: str() = int()
  7. 讨论 innodb_log_block_size 变量
  8. Python 这么热,运维要不要追赶 Python 的热潮?
  9. caffe上手:微调CaffeNet用于车颜色识别
  10. 关于消灭冲击波的蠕虫
  11. lammps学习总结3
  12. 341编程器 软硬件
  13. matlab建空数组,matlab数组的创建与操作
  14. 你绝没看如此详细的PDF去水印教程
  15. NB-IoT技术发展史漫谈(NB-IoT专栏—拓展篇1)
  16. 微信公众平台技术揭秘之Referer的妙用
  17. 国外html游戏发展历史,网页游戏技术发展史 早期到当前10几年历程
  18. java全角数字_Java全角、半角字符的关系以及转换
  19. 气质由内而外 都市白领3个饮食排毒法则
  20. 如何升级Windows 11正式版?四种方案都在这里了

热门文章

  1. oracle sqltune,DBMS_SQLTUNE
  2. 丝印代码html,丝印代码反查型号:ic上的丝印为HH1YA,封装是SOT23-6的,请问是什么型号呢?...
  3. 机器学习-分类模型-置信概率
  4. java url类_Java中的URL类和示例 - Break易站
  5. Python2.7获取QQ好友头像
  6. Random Forest和Gradient Tree Boosting模型如何调参
  7. 驱动程序安装方法大全(转)
  8. python微信支付接口_Python微信支付APIv3签名
  9. 1 win10双系统安装ubuntu16.04和18.04(问题详细记录)
  10. 怎么使用手机便签软件将图片上的文字扫描出来