`
kanwoerzi
  • 浏览: 1644631 次
文章分类
社区版块
存档分类
最新评论

红黑树源码及错误解析

 
阅读更多

/* 作者:田帅

学校:**大学

版本:红黑树初始版本

*/

#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 之后加上 大括号

分享到:
评论

相关推荐

    linux红黑树源码

    linux中的红黑树,被广泛的应用在linux内核的模块中。 高质量的代码值得拥有。

    红黑树 windowsx64 SDK和源码

    资源包括红黑树源码(VC2008动态库形式)、调用示例源码、用户开发文档。实现以下强大功能: 1、 支持自定义键值比较函数 2、 支持删除节点回调函数 3、 支持插入节点 4、 支持根据键值进行精确查询节点 5、 支持...

    delphi红黑树源码

    delphi编写的,从网上下载的红黑树实现. 欢迎大家下载

    红黑树源码 c++实现

    c++实现的红黑二叉树源码,已经过调试,可运行。

    一个红黑树实现c源码

    一个红黑树的c语言完整实现,代码清晰易读。初学者可以更好地了解红黑树的性质

    红黑树.源码

    红黑树

    红黑树代码

    红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树红黑树...

    红黑树的c实现源码与教程

    红黑树的c实现源码与剖析 原作者:那谁 源码剖析作者:July ===================== July说明: 由于原来的程序没有任何一行注释,我把它深入剖析,并一行一行的添加了注释, 详情请参见此文: 教你彻底实现红黑树:...

    红黑树C++代码实现

    描述: 实现红黑树、二叉搜索树相关算法:插入(红黑树涉及树的调整:左旋右旋等),删除,搜索(指定Key值节点)。 另外,红黑树实现计算树黑高的算法。 1).插入测试,输入 8,11,17,15,6,1,22,25,27,...

    红黑树的源码与测试函数

    rbtree源码与测试函数

    红黑树实现源码

    关于红黑树的功能实现

    红黑树的Java实现参考源码

    红黑树的增删查的Java实现,注解详细,可配合该博客以参考学习:http://blog.csdn.net/oLanMoMo/article/details/50686267

    红黑树源码

    红黑树的c实现源码与教程.pdf,讲述了红黑树的实现原理,帮助更多的人理解红黑树的内部逻辑

    红黑树原理详解

    红黑树原理详解 红黑树原理详解 红黑树原理详解 红黑树原理详解

    红黑树代码实现及分析2

    红黑树代码实现及分析

    Linux源码红黑树源码案例

    从Linux的源码提取出来的红黑树,经过修改,并带有调用案例,可执行。

    拆解改写的独立版红黑树源码

    拆解改写的独立版红黑树源码

    数据结构课程设计红黑树源码

    结对靠谱,本人经过验收的,适合初学者参考。

    大数据学习之旅-02-红黑树源码

    源码+zookeeper-3.4.7.tar.gz 文章https://blog.csdn.net/qq_39188039/article/details/86216908

Global site tag (gtag.js) - Google Analytics