当前位置: 首页 > news >正文

红黑树源码及错误解析

 

/* 作者:田帅

学校:**大学

版本:红黑树初始版本

*/

#include"stdio.h"

#include"malloc.h"

#define MIN -99999999 //不要加等号

#define MAX 99999999

struct node

{

long key;

char color;

struct node *p;

struct node *leftChild;

struct node *rightChild;

};

node *nil,*root;//创建根节点和叶子节点

int printnode=0;

node *CreateNode(int key);

void RB_insert_fixUp(node *T,node *z);

void nil_create();//叶子节点创建

void RB_insert(node *T,node *z);//弄算法导论上非递归的吧

void left_rotate(node *T,node *z);//向左旋转

void right_rotate(node *T,node *z);

void PrintRBTree(node *T);//输出树

void nil_create()//叶子节点创建

{

nil=(node *)malloc(sizeof(node));

root=(node *)malloc(sizeof(node));

nil->key=MIN;

nil->color='B';

//nil->p=NULL;//这里注意

nil->leftChild=nil;

nil->rightChild=nil;

root=nil;

}

node *CreateNode(int key)

{

node *x = (node *)malloc(sizeof(node));

x->color ='R';

x->key = key;

x->leftChild = nil;

x->rightChild = nil;

x->p = NULL;

return x;

}

void RB_insert(node *T,node *z)//弄算法导论上非递归的吧

{

node *x,*y;//y用来记录父节点

x=root;//这里应该是 根节点 跟形式参数重复 会造成错误

y=nil;

while(x!=nil)//x为要插入的位置de父节点 y为x的父节点

{

y=x;

if(x->key>z->key)

x=x->leftChild;

else

x=x->rightChild;

}

z->p=y;

if(y==nil)//初始化 插入到空树种

root=z;

else if(z->key<y->key)

y->leftChild=z;

else

y->rightChild=z;

z->leftChild=nil;

z->rightChild=nil;

z->color='R';

RB_insert_fixUp(T,z);

}

void RB_insert_fixUp(node *T,node *z)

{

node *y;

while(z->p->color=='R')//插入节点 是红节点 如果父节点也是红节点 则需要调整

{

if(z->p==z->p->p->leftChild)//插入的节点的父节点 是祖父节点的左孩子

{

y=z->p->p->rightChild;//祖父节点的右孩子

if(y->color=='R')//二叔是 红色的O(∩_∩)O哈哈~

{

z->p->color='B';

y->color='B';

z->p->p->color='R';

z=z->p->p;

}

else

{//这个地方一定要加上 {

if(z==z->p->rightChild)//二叔是黑色 且 要插入的节点是右孩子

{

z=z->p;

left_rotate(T,z);

}

z->p->color='B';//二叔是黑色 且要插入的节点是左孩子

z->p->p->color='R';

// z->p->p->color='R'; //???????????????????????????

right_rotate(T,z->p->p);

}

}

else//插入的节点的父节点 是祖父节点的右孩子

{

y=z->p->p->leftChild;//祖父节点的左孩子

if(y->color=='R')//二叔是 红色的O(∩_∩)O哈哈~

{

z->p->color='B';

y->color='B';

z->p->p->color='R';

z=z->p->p;//???????

}

else

{

if(z==z->p->leftChild)//二叔是黑色 且 要插入的节点是左孩子

{

z=z->p;

right_rotate(T,z);

}

z->p->color='B';//二叔是黑色 且要插入的节点是右孩子

z->p->p->color='R';

left_rotate(T,z->p->p);

}

}

}

root->color='B';//这里不要落下!!!

}

void left_rotate(node *T,node *z)//向左旋转

{

node *y;

y=z->rightChild;//让y 为要旋转的节点的右子树

z->rightChild=y->leftChild;

if(y->leftChild!=nil)

y->leftChild->p=z;

y->p=z->p;//将要旋转节点切下

if(z->p==nil)

root=y;

else if(z==z->p->leftChild)//要旋转节点是 其父节点左孩子

z->p->leftChild=y;

else//要旋转节点是 其父节点右孩子

z->p->rightChild=y;

y->leftChild=z;//将要旋转节点挂到 代替它的孩子的左子树上

z->p=y;

}

void right_rotate(node *T,node *z)

{

node *y;

y=z->leftChild;//让y 为要旋转的节点的左子树

z->leftChild=y->rightChild;

if(y->rightChild!=nil)

y->rightChild->p=z;

y->p=z->p;//将要旋转节点切下

if(z->p==nil)

root=y;

else if(z==z->p->leftChild)//要旋转节点是 其父节点左孩子

z->p->leftChild=y;

else//要旋转节点是 其父节点右孩子

z->p->rightChild=y;

y->rightChild=z;//将要旋转节点挂到 代替它的孩子的左子树上

z->p=y;

}

void PrintRBTree(node *T)

{

int i;

if(T != nil)

{

for(i = 0; i <= printnode;i++)

printf(" ");

printf("(%d",T->key);

if(T->color == 'B')

printf("B,\n");

else

printf("R,\n");

printnode++;

PrintRBTree(T->leftChild);

PrintRBTree(T->rightChild);

printnode--;

for(int j = 0; j <= printnode;j++)

printf(" ");

printf("),\n");

}

else

{

for(int i = 0; i <= printnode;i++)

printf(" ");

printf("Nil,\n");

}

}

void INORDER_TREE_WALK(struct node* x) //中根遍历

{

//printf("%ld %c ",x->key,x->color); //debug 先根遍历

if(x->leftChild!=nil)

INORDER_TREE_WALK(x->leftChild);

printf("%ld %c ",x->key,x->color);

if(x->rightChild!=nil)

INORDER_TREE_WALK(x->rightChild);

}

int main()

{ //long a[11]={4,1,3,2,16,9,10,14,8,7};

//long a[10]={10,9,8,7,6,5,4,3,2,1};

// long a[10]={1,2,3,4,5,6,7,8,9,10};

// long a[]={1,2,3,4,5,6,7,8,9,10};//这个可以

long a[]={4,1,3,2,16,9,10,14,8,7};//这个不可以

node *z[11];

nil_create();

// nil=(node *)malloc(sizeof(node));

// nil=nil_create();

printf(" 1111111");

for(int j = 0; j <10; j++)

{

printf(" 222222 ");

z[j]=CreateNode(a[j]);

RB_insert(root,z[j]);

}

printf(" 222222 ");

INORDER_TREE_WALK(root);

// PrintRBTree(root);

return 0;

}

出现的错误及调试方法:

总是到insert_fix_up时候出现错误;原因是 第三种情况 要写在 if(y.color=='R') else{ if() ; ********} 不要忘记在else 之后加上 大括号

转载于:https://www.cnblogs.com/tianshuai11/archive/2011/11/29/2477235.html

相关文章:

  • 修复垂直滑动RecyclerView嵌套水平滑动RecyclerView水平滑动不灵敏问题
  • 无线网络覆盖 郑州大学第三届acm比赛试题 n 199
  • 回数
  • 生成备案号例如80-027-1-001 规则为:企业编号-所在区号-产品类别-序号
  • 颠覆你的认知,带你领略史上最为齐全的微软黑科技之旅
  • 时代杂志评年度十大科技产品 iPad 2居首
  • 成功恢复FAT32误格式化后所有碎片文件(已覆盖的除外)
  • maya羽毛制作插件
  • 如何使用sendEmail发送邮件
  • TightVNC 企业内部部署
  • 请读者帮忙投个票喔
  • 网吧游戏的三层更新
  • DOM常用属性和方法汇总
  • 享元模式(Flyweight)解析例子
  • msdb.dbo.suspect_pages
  • C++回声服务器_9-epoll边缘触发模式版本服务器
  • download使用浅析
  • ECMAScript入门(七)--Module语法
  • ERLANG 网工修炼笔记 ---- UDP
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • Java反射-动态类加载和重新加载
  • Js基础知识(四) - js运行原理与机制
  • k8s 面向应用开发者的基础命令
  • SSH 免密登录
  • Webpack4 学习笔记 - 01:webpack的安装和简单配置
  • 从伪并行的 Python 多线程说起
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 基于webpack 的 vue 多页架构
  • 目录与文件属性:编写ls
  • 前端 CSS : 5# 纯 CSS 实现24小时超市
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • 智能网联汽车信息安全
  • 阿里云API、SDK和CLI应用实践方案
  • !$boo在php中什么意思,php前戏
  • # Swust 12th acm 邀请赛# [ K ] 三角形判定 [题解]
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • #include<初见C语言之指针(5)>
  • #NOIP 2014# day.2 T2 寻找道路
  • #大学#套接字
  • $.ajax中的eval及dataType
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • $con= MySQL有关填空题_2015年计算机二级考试《MySQL》提高练习题(10)
  • (1)(1.11) SiK Radio v2(一)
  • (二)fiber的基本认识
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (六)c52学习之旅-独立按键
  • (十)T检验-第一部分
  • (实战)静默dbca安装创建数据库 --参数说明+举例
  • (四) Graphivz 颜色选择
  • (转)ObjectiveC 深浅拷贝学习
  • .bat批处理(二):%0 %1——给批处理脚本传递参数
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
  • .Net(C#)自定义WinForm控件之小结篇