全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

数据结构 红黑树的详解

数据结构 红黑树的详解

红黑树是具有下列着色性质的二叉查找树:

1.每一个节点或者着红色,或者着黑色。

2.根是黑色的。

3.如果一个节点是红色的,那么它的子节点必须是黑色。

4.从一个节点到一个NULL指针的每一条路径必须包含相同数目的黑色节点。

下面是一棵红黑树。


1.自底向上插入

通常把新项作为树叶放到树中。如果我们把该项涂成黑色,那么违反条件4,因为将会建立一条更长的黑节点路径。因此这一项必须涂成红色。如果它的父节点是黑色的,插入完成。如果父节点是红色的,那么违反条件3。在这种情况下我们必须调整该树以满足条件3。用于完成这项目任务的基本操作是颜色的改变和树的旋转。

如果新插入的节点的父节点是黑色,那么插入完成。

如果父节点是红色,那么有几种情形需要考虑。首先,假设这个父节点的兄弟是黑色(NULL节点约定为黑色)。这对于插入3或8是适用的,但对插入99不适用。令X是新加的树叶,P是它的父节点,S是该父节点的兄弟,G是祖父节点情况一:父节点的兄弟是黑色的。通过操作使得到达A,B,C的黑色路径保持不变(满足条件4),而且没有连续的红色节点(满足条件3).。



情况二:父节点的兄弟是红色的。



2.自顶向下删除

红黑树中的删除可以是自顶向下进行。每一件工作都归结于能够删除一片树叶。这是因为,要删除一个带有两个儿子的节点,我们用右子树上的最小节点代替它;该节点最多有一个儿子,然后将该节点删除。只有一个右儿子的节点可以用相同的方式删除,而只有一个左儿子的节点通过用其左子树上最大的节点替换,然后可将该节点删除。但是假如删除的节点不是红色的,那么就会破坏红黑树的平衡。解决的方法就是保证从上到下删除期间树叶是红色的。

在整个讨论中,令X为当前节点,T是它的兄弟,而P是它们的父亲。开始时我们把根涂成红色。当沿着树向下遍历时,我们设法保证X是红色的。当我们到达一个新的节点时,我们要确信P是红色的并且X和T是黑色的(因为不能有两个相连的红色节点)。存在两种主要情形。 情况一:X有两个黑色儿子。此时有三个子情况。 (1)T有两个黑儿子,那么我们可以翻转X、T、P的颜色来保持这种不变性。
(2)T的左儿子是红色的
(3)T的右儿子是红色的
情况二:X的儿子之一是红的。在这种情况下,我们落到下一层,得到新的X、T、P。如果幸运,X落在红儿子上。则我们继续前行。如果不是这样,那么我们知道T将是红的,而X和P将是黑的。我们可以旋转T和P,使得X的新父亲是红的;当然X和它的祖父是黑的。此时我们可以回到第一种主情况。
3.红黑树的实现 3.1 头文件
// 
// RedBlackTree.h 
// RedBlackTree3 
// 
// Created by Wuyixin on 2017/7/3. 
// Copyright © 2017年 Coding365. All rights reserved. 
// 
 
#ifndef RedBlackTree_h 
#define RedBlackTree_h 
 
#include <stdio.h> 
#include <stdlib.h> 
#include <limits.h> 
 
 
typedef int ElementType; 
 
typedef enum { 
 RED, 
 BLACK 
} COLOR; 
 
typedef struct RedBlackNode *RedBlackTree,*Position; 
 
struct RedBlackNode{ 
 ElementType Element; 
 COLOR Color; 
 RedBlackTree Left; 
 RedBlackTree Right; 
}; 
 
static Position NullNode = NULL; 
static Position Header; 
static Position X,P,GP,GGP; 
/* 初始化 */ 
RedBlackTree Initialize(); 
/* 插入 */ 
RedBlackTree Insert(RedBlackTree T,ElementType Item); 
/* 删除 */ 
RedBlackTree Remove(RedBlackTree T,ElementType Item); 
/* 查找 */ 
Position Find(RedBlackTree T,ElementType Item); 
/* 遍历 */ 
void Travel(RedBlackTree T); 
 
 
 
 
#endif /* RedBlackTree_h */ 

3.2 实现文件

// 
// RedBlackTree.c 
// RedBlackTree3 
// 
// Created by Wuyixin on 2017/7/3. 
// Copyright © 2017年 Coding365. All rights reserved. 
// 
 
#include "RedBlackTree.h" 
 
 
/* 左旋转 */ 
static Position SingleRotateLeft(Position X); 
/* 右旋转 */ 
static Position SingleRotateRight(Position X); 
/* 旋转 */ 
static Position Rotate(Position Parent,Position* Origin ,ElementType Item); 
 
 
/* 左旋转 */ 
static Position SingleRotateLeft(Position T){ 
 Position TL = T->Left; 
 T->Left = TL->Right; 
 TL->Right = T; 
 return TL; 
} 
/* 右旋转 */ 
static Position SingleRotateRight(Position T){ 
 Position TR = T->Right; 
 T->Right = TR->Left; 
 TR->Left = T; 
 return TR; 
} 
 
/* 旋转 */ 
static Position Rotate(Position Parent,Position* Origin ,ElementType Item){ 
 if (Item < Parent->Element){ 
 if (Origin != NULL) 
  *Origin = Parent->Left; 
 return Parent->Left = Item < Parent->Left->Element ? 
 SingleRotateLeft(Parent->Left) : 
 SingleRotateRight(Parent->Left); 
 } 
 else{ 
 if (Origin != NULL) 
  *Origin = Parent->Right; 
 return Parent->Right = Item < Parent->Right->Element ? 
 SingleRotateLeft(Parent->Right) : 
 SingleRotateRight(Parent->Right); 
 } 
 
} 
 
 
/* 初始化 */ 
RedBlackTree Initialize(){ 
 
 if (NullNode == NULL){ 
 NullNode = malloc(sizeof(struct RedBlackNode)); 
 if (NullNode == NULL) 
  exit(EXIT_FAILURE); 
 NullNode->Element = INT_MAX; 
 NullNode->Color = BLACK; 
 NullNode->Left = NullNode->Right = NullNode; 
  
 } 
 
 Header = malloc(sizeof(struct RedBlackNode)); 
 if (Header == NULL) 
 exit(EXIT_FAILURE); 
 
 /* header的值为无穷小,所以根插入到右边*/ 
 Header->Element = INT_MIN; 
 Header->Left = Header->Right = NullNode; 
 Header->Color = BLACK; 
 
 return Header; 
 
} 
 
static Position GetSibling(Position Parent,Position X){ 
 if (Parent->Element == INT_MIN) 
 return NULL; 
 if (X == Parent->Left) 
 return Parent->Right; 
 else if (X == Parent->Right) 
 return Parent->Left; 
 else 
 return NULL; 
} 
 
void HandleReorientForInsert(ElementType Item){ 
 Position Sibling,Origin; 
 
 /* 当P与X同时为红节点才进行调整 */ 
 if (X == NullNode || !(P->Color == RED && X->Color == RED)) 
 return ; 
 
 
 Sibling = GetSibling(GP, P); 
 
 if (Sibling == NULL) 
 return ; 
 
 
 /* GP,P,X是成字型,调整为一字型 */ 
 if ((GP->Element < Item) != (P->Element < Item)){ 
 P = Rotate(GP, &Origin,Item); 
 X = Origin; 
 } 
 
 GP = Rotate(GGP, &Origin,Item); 
 P = Origin; 
 
 /* P的兄弟是黑色的 */ 
 if (Sibling->Color == BLACK){ 
  
 GP->Color = BLACK; 
 GP->Left->Color = RED; 
 GP->Right->Color = RED; 
  
 } 
 /* P的兄弟是红的 */ 
 else{ 
  
 GP->Color = RED; 
 GP->Left->Color = BLACK; 
 GP->Right->Color = BLACK; 
 } 
} 
 
RedBlackTree _Insert(RedBlackTree T,ElementType Item){ 
 
 if (T == NullNode){ 
 T = malloc(sizeof(struct RedBlackNode)); 
 T->Element = Item; 
 T->Left = T->Right = NullNode; 
 T->Color = RED; 
 } 
 else if (Item < T->Element) 
 T->Left = _Insert(T->Left, Item); 
 else if (Item > T->Element) 
 T->Right = _Insert(T->Right, Item); 
 /* 重复值不插入 */ 
 
 X = P,P = GP,GP = GGP, GGP = T; 
 
 HandleReorientForInsert(Item); 
 
 return T; 
} 
 
/* 插入 */ 
RedBlackTree Insert(RedBlackTree T,ElementType Item){ 
 GGP = GP = P = X = NullNode; 
 T = _Insert(T, Item); 
 T->Right->Color = BLACK; 
 return T; 
} 
 
 
static void _HandleReorientForRemove(ElementType Item){ 
 RedBlackTree Sibling,R; 
 Sibling = GetSibling(P, X); 
 
 if (Sibling == NULL) 
 return ; 
 
 if (Sibling->Left->Color == BLACK && Sibling->Right->Color == BLACK){ 
 P->Color = BLACK; 
 X->Color = RED; 
 Sibling->Color = RED; 
 }else if(Sibling->Left->Color == RED){ 
 R = Sibling->Left; 
  
 P->Color = BLACK; 
 X->Color = RED; 
  
 R = Rotate(P, NULL, R->Element); 
 GP = Rotate(GP, NULL, R->Element); 
  
 }else if (Sibling->Right->Color == RED){ 
 X->Color = RED; 
 P->Color = BLACK; 
 Sibling->Color = RED; 
 Sibling->Right->Color = BLACK; 
  
 GP = Rotate(GP, NULL, Sibling->Element); 
  
 } 
} 
 
static void HandleReorientForRemove(RedBlackTree T, ElementType Item){ 
 RedBlackTree Sibling,Origin,OriginGP; 
 if (X == NullNode) 
 return ; 
 
 /* X有两个黑儿子 */ 
 if (X->Left->Color == BLACK && X->Right->Color == BLACK){ 
 _HandleReorientForRemove(Item); 
 }else{ 
  
 OriginGP = GP; 
 /* 落到下一层 */ 
 GP = P; P = X; 
  
 if (Item < X->Element) 
  X = X->Left; 
 else 
  X = X->Right; 
  
  
 Sibling = GetSibling(P, X); 
 /* 如果X是黑的,则Sibling是红的,旋转 */ 
 if (X->Color == BLACK){ 
  GP = Rotate(GP, &Origin, Sibling->Element); 
  P = Origin; 
  GP->Color = BLACK; 
  P->Color = RED; 
  _HandleReorientForRemove(Item); 
  
 } 
  
 /* 恢复X,PX,GP。由于X是当前节点 如果当前节点正是Item,不恢复会影响查找 */ 
 if (X->Element == Item){ 
  X = P ; P = GP ;GP = OriginGP; 
 } 
  
 } 
} 
 
/* 删除 */ 
RedBlackTree Remove(RedBlackTree T,ElementType Item){ 
 
 ElementType Origin; 
 Position DeletePtr; 
 Origin = NullNode->Element; 
 
 NullNode->Element = Item; 
 
 GP = P = X = T; 
 
 /* 根染红 */ 
 T->Right->Color = RED; 
 
 while (X->Element != Item) { 
 GP = P ; P = X; 
 if (Item < X->Element) 
  X = X->Left; 
 else 
  X = X->Right; 
  
 HandleReorientForRemove(T, Item); 
 } 
 
 
 NullNode->Element = Origin; 
 
 /* 找到 */ 
 if (X != NullNode){ 
 DeletePtr = X;  
 if (X->Left != NullNode){ 
  GP = P ; P = X; X = X->Left; 
  HandleReorientForRemove(T, Item); 
  /* 寻找左子树最大值替换 */ 
  while (X->Right != NullNode) { 
  GP = P ; P = X; 
  X = X->Right; 
  HandleReorientForRemove(T, Item); 
  } 
  if (X == P->Left) 
  P->Left = X->Left; 
  else 
  P->Right = X->Left; 
  
 }else if (X->Right != NullNode){ 
  GP = P ; P = X; X = X->Right; 
  HandleReorientForRemove(T, Item); 
  /* 寻找右子树最大值替换 */ 
  while (X->Left != NullNode) { 
  GP = P ; P = X; 
  X = X->Left; 
  HandleReorientForRemove(T, Item); 
  } 
  if (X == P->Left) 
  P->Left = X->Right; 
  else 
  P->Right = X->Right; 
 }else{ 
  /* X是树叶 */ 
  if (X == P->Left) 
  P->Left = NullNode; 
  else 
  P->Right = NullNode; 
 } 
  
 DeletePtr->Element = X->Element; 
 free(X); 
  
 } 
 
 /* 根染黑 */ 
 T->Right->Color = BLACK; 
 
 return T; 
} 
 
 
 
typedef enum { 
 ROOT, 
 LEFT, 
 RIGHT 
} NodeType; 
 
static char *TypeC; 
static char *ColorC; 
 
void _Travel(RedBlackTree T , NodeType Type){ 
 
 if (T != NullNode){ 
  
 if (Type == ROOT) 
  TypeC = "root"; 
 else if (Type == LEFT) 
  TypeC = "left"; 
 else if (Type == RIGHT) 
  TypeC = "right"; 
  
 if (T->Color == BLACK) 
  ColorC = "black"; 
 else 
  ColorC = "red"; 
  
 printf("(%d,%s,%s) ",T->Element,ColorC,TypeC); 
  
 _Travel(T->Left, LEFT); 
 _Travel(T->Right, RIGHT); 
  
 } 
 
} 
 
/* 遍历 */ 
void Travel(RedBlackTree T){ 
 _Travel(T->Right,ROOT); 
} 

3.3 调用

// 
// main.c 
// RedBlackTree3 
// 
// Created by Wuyixin on 2017/7/3. 
// Copyright © 2017年 Coding365. All rights reserved. 
// 
 
#include "RedBlackTree.h" 
int main(int argc, const char * argv[]) { 
   
  RedBlackTree T = Initialize(); 
   
  T = Insert(T, 10); 
  T = Insert(T, 85); 
  T = Insert(T, 15); 
  T = Insert(T, 70); 
  T = Insert(T, 20); 
  T = Insert(T, 60); 
  T = Insert(T, 30); 
  T = Insert(T, 50); 
  T = Insert(T, 65); 
  T = Insert(T, 80); 
  T = Insert(T, 90); 
  T = Insert(T, 40); 
  T = Insert(T, 5); 
  T = Insert(T, 55); 
  T = Insert(T, 100); 
   
   
  T = Remove(T, 100); 
   
   
  Travel(T); 
   
   
  return 0; 
} 

以上就是关于数据结构与算法中红黑二叉树的详解,如有疑问请留言或者到本站的社区讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


# 数据结构  # 红黑树  # 红黑树详解  # 红黑树的使用详解  # 数据结构之红黑树详解  # 红黑树的插入详解及Javascript实现方法示例  # 红黑  # 子树  # 我们可以  # 有两个  # 遍历  # 将是  # 字型  # 在这种情况下  # 将该  # 树上  # 有一个  # 下一层  # 这一  # 就会  # 将会  # 最多  # 如有  # 一是  # 两种 


相关文章: 哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?  武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?  制作国外网站的软件,国外有哪些比较优质的网站推荐?  网站制作免费,什么网站能看正片电影?  黑客如何利用漏洞与弱口令入侵网站服务器?  寿县云建站:智能SEO优化与多行业模板快速上线指南  网站海报制作教学视频教程,有什么免费的高清可商用图片网站,用于海报设计?  建站之星安装后界面空白如何解决?  打鱼网站制作软件,波克捕鱼官方号怎么注册?  GML (Geography Markup Language)是什么,它如何用XML来表示地理空间信息?  如何快速上传自定义模板至建站之星?  北京建设网站制作公司,北京古代建筑博物馆预约官网?  建站之星免费版是否永久可用?  宝塔新建站点报错如何解决?  如何确保西部建站助手FTP传输的安全性?  如何在IIS中配置站点IP、端口及主机头?  制作企业网站建设方案,怎样建设一个公司网站?  python的本地网站制作,如何创建本地站点?  php json中文编码为null的解决办法  湖南网站制作公司,湖南上善若水科技有限公司做什么的?  如何快速搭建支持数据库操作的智能建站平台?  制作网站的软件免费下载,免费制作app哪个平台好?  如何选择靠谱的建站公司加盟品牌?  建站之星代理商如何保障技术支持与售后服务?  免费视频制作网站,更新又快又好的免费电影网站?  制作假网页,招聘网的薪资待遇,会有靠谱的吗?一面试又各种折扣?  网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?  公司门户网站制作流程,华为官网怎么做?  网站网页制作电话怎么打,怎样安装和使用钉钉软件免费打电话?  建站三合一如何选?哪家性价比更高?  已有域名和空间如何搭建网站?  大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?  制作网站的模板软件,网站怎么建设?  宠物网站制作html代码,有没有专门介绍宠物如何养的网站啊?  淘宝制作网站有哪些,淘宝网官网主页?  Swift开发中switch语句值绑定模式  孙琪峥织梦建站教程如何优化数据库安全?  高防服务器租用指南:配置选择与快速部署攻略  网站制作壁纸教程视频,电脑壁纸网站?  西安制作网站公司有哪些,西安货运司机用的最多的app或者网站是什么?  建站之星与建站宝盒如何选择最佳方案?  南京网站制作费用,南京远驱官方网站?  官网自助建站平台指南:在线制作、快速建站与模板选择全解析  如何通过西部建站助手安装IIS服务器?  C++中引用和指针有什么区别?(代码说明)  如何在阿里云服务器自主搭建网站?  早安海报制作网站推荐大全,企业早安海报怎么每天更换?  邀请函制作网站有哪些,有没有做年会邀请函的网站啊?在线制作,模板很多的那种?  如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?  学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。