紅/黑樹狀結構源碼及錯誤解析

來源:互聯網
上載者:User
 

/* 作者:田帥

學校:**大學

版本:紅/黑樹狀結構初始版本

*/

#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 之後加上 大括弧

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.