您的位置:首页 > 其它

经过自动压力测试的红黑树(删除功能完备)

2011-11-28 18:05 197 查看
#include <stdio.h>

#include <stdlib.h>

#define COUNT 10000

#define RAND (4*COUNT)

int error_label=0;

#pragma pack(1)

typedef enum _color

{

RED,

BLACK

}color;

typedef struct _data

{

int value;

}data;

typedef struct _redblack

{

color m_color;

int m_data;

struct _redblack *parent;

struct _redblack *left;

struct _redblack *right;

}redblack;

typedef struct _wrapredblack

{

struct _wrapredblack *next;

redblack real;

}wrapredblack;

typedef struct _wrapdata

{

redblack *root;

int size;

}wrapdata;

#pragma pack()

wrapredblack global[2*RAND];

wrapredblack *head;

wrapredblack *tail;

wrapdata *global_node;

void init( )

{

int i,j;

for(i=0;i<RAND-1;i++)

{

global[i].next=&global[i+1];

}

head=&global[0];

tail=&global[RAND-1];

}

redblack *mycalloc ( )

{

redblack *temp=&head->real;

head=head->next;

return temp;

// return (redblack *) calloc (1 ,sizeof (redblack));

}

int checkvalid ( redblack *del,redblack *root)

{

if(!root)

{

return 0;

}

else

{

if(checkvalid(del,root->left))

{

return 1;

}

if(checkvalid (del,root->right))

{

return 1;

}

if (root==del)

{

return 1;

}

else

{

return 0;

}

}

}

void myfree (redblack *node)

{

wrapredblack *temp = (wrapredblack *)( (int)node-4);

temp->next=0;

node->left=node->right=node->parent=0;

tail->next=temp;

tail=temp;

if(checkvalid (node,global_node->root))

{

exit(0);

}

return ;

}

int compare ( int data ,redblack *right)

{

if(data > right->m_data)

{

return 1;

}

else if(data == right->m_data)

{

return -1;

}

else

{

return 0;

}

}

redblack * newstruct ( int value)

{

redblack *newnode;

newnode=(redblack *)mycalloc ();

newnode->m_color=RED;

newnode->m_data =value;

return newnode;

}

void rotate_right ( redblack * left ,redblack *right )

{

right->left=left->right;

if(left->right)

{

left->right->parent=right;

}

left->right=right;

left->parent=right->parent;

if(right->parent)

{

if(right->parent->left==right)

{

right->parent->left=left;

}

else

{

right->parent->right=left;

}

}

right->parent=left;

}

void rotate_left ( redblack * left ,redblack *right )

{

left->right=right->left;

if (right->left)

{

right->left->parent=left;

}

right->left=left;

right->parent=left->parent;

if(left->parent)

{

if(left->parent->right==left)

{

left->parent->right=right;

}

else

{

left->parent->left=right;

}

}

left->parent=right;

}

int mid_print (redblack *root,int level)

{

int left,right;

if(level>40)

{

printf("error\n");

error_label=1;

return 100000 ;

}

if (!root)

{

return 0;

}

else

{

left=mid_print (root ->left,level+1);

printf("{address=%x color=%s,level=%d ,value=%d} ",root ,root->m_color==RED?"red":"black",level ,root->m_data);

// printf(" %d ",root->m_data->value);

right= mid_print (root ->right,level+1);

return left+right+1;

}

}

int check (redblack *root)

{

int left,right;

if (!root)

{

return 0;

}

else

{

left=check (root ->left);

right= check (root ->right);

if(left||right)

{

return 1;

}

if( root->left && ( root->left->m_data > root->m_data || root->left->parent!=root) )

{

return 1;

}

if( root->right && ( root->right->m_data < root->m_data || root->right->parent!=root))

{

return 1;

}

else

{

return 0;

}

}

}

void left_print (redblack *root)

{

if (!root)

{

return;

}

else

{

printf("%d ",root->m_data);

left_print (root ->left);

left_print (root ->right);

}

}

void right_print (redblack *root)

{

if (!root)

{

return;

}

else

{

right_print (root ->left);

right_print (root ->right);

printf("%d ",root->m_data);

}

}

int depth(redblack *root)

{

int left,right;

if (!root)

{

return 0;

}

else

{

left=depth(root->left);

right=depth(root->right);

return left>right ? ( left+1):(right+1);

}

}

void insert_fixup (wrapdata *node , redblack *newnode)

{

redblack *curnode;

redblack *parent;

redblack *grandparent;

redblack *tmp;

curnode=newnode;

parent=curnode->parent;

while( curnode->m_color==RED && parent ->m_color==RED)

{

grandparent=parent->parent;

if ( curnode == parent->left)

{

if ( parent == grandparent->left)

{

curnode->m_color=BLACK;

rotate_right ( parent , grandparent);

curnode=parent;

parent=curnode->parent;

if(!parent )

{

node->root=curnode;

break;

}

}

else

{

// printf("nothing");

rotate_right (curnode, parent );

tmp=parent;

parent=curnode;

curnode=tmp;

curnode->m_color=BLACK;

rotate_left (grandparent ,parent );

curnode=parent;

parent=curnode->parent;

if(!parent )

{

node->root=curnode;

break;

}

}

}

else

{

if ( parent== grandparent->right)

{

curnode->m_color=BLACK;

rotate_left (grandparent,parent );

curnode=parent;

parent=curnode->parent;

if(!parent )

{

node->root=curnode;

break;

}

}

else

{

// printf("nothing");

rotate_left ( parent ,curnode);

tmp=parent;

parent=curnode;

curnode=tmp;

curnode->m_color=BLACK;

rotate_right (parent,grandparent );

curnode=parent;

parent=curnode->parent;

if(!parent )

{

node->root=curnode;

break;

}

}

}

}

}

redblack * find(redblack *root ,int data)

{

if (! root)

{

return NULL;

}

else

{

if ( data == root->m_data)

{

return root;

}

else if ( data > root->m_data)

{

return find (root ->right ,data);

}

else

{

return find (root->left ,data );

}

}

}

redblack * next (redblack * mostleft)

{

// if

if(! mostleft->left)

{

return mostleft;

}

else

{

return next ( mostleft->left);

}

}

void delete_fixup (wrapdata *node, redblack *curnode ,int mode)

{

redblack *parent;

redblack *uncle;

redblack *uncle_left;

redblack *uncle_right;

while(1)

{

if (curnode->m_color==RED)

{

curnode->m_color=BLACK;

parent=curnode->parent;

if(!parent)

{

node->root=curnode;

}

return ;

}

else

{

parent=curnode->parent;

if(!parent)

{

node->root=curnode;

return ;

}

if(0==mode)

{

uncle=parent->right;

if(!uncle)

{

return ;

}

if (uncle->m_color== RED)

{

uncle->m_color=BLACK;

parent->m_color=RED;

rotate_left (parent,uncle );

if (!uncle->parent)

{

node->root=uncle;

}

}

else

{

uncle_left=uncle->left;

uncle_right=uncle->right;

if( (!uncle_left || uncle_left->m_color==BLACK )

&&

(!uncle_right || uncle_right->m_color==BLACK))

{

uncle->m_color=RED;

curnode=parent;

}

else

{

if( !uncle_right || (uncle_right&& uncle_right->m_color==RED))

{

uncle->m_color=parent->m_color;

parent->m_color=BLACK;

if(uncle_right)

{

uncle_right->m_color=BLACK;

}

rotate_left( parent,uncle);

if (!uncle->parent)

{

node->root=uncle;

}

return ;

}

else

{

uncle_left->m_color=BLACK;

uncle->m_color=RED;

rotate_right(uncle_left,uncle);

uncle=parent->right;

uncle->right=uncle->right;

uncle->m_color=parent->m_color;

parent->m_color=BLACK;

uncle_right->m_color=BLACK;

rotate_left( parent,uncle);

if (!uncle->parent)

{

node->root=uncle;

}

return ;

}

}

}

}

else

{

uncle=parent->left;

if(!uncle)

{

return ;

}

if (uncle->m_color== RED)

{

uncle->m_color=BLACK;

parent->m_color=RED;

rotate_right (uncle ,parent);

if (!uncle->parent)

{

node->root=uncle;

}

}

else

{

uncle_left=uncle->left;

uncle_right=uncle->right;

if( (!uncle_left || uncle_left->m_color==BLACK )

&&

(!uncle_right || uncle_right->m_color==BLACK))

{

uncle->m_color=RED;

curnode=parent;

}

else

{

if( !uncle_left || ( uncle_left && uncle_left->m_color==RED))

{

uncle->m_color=parent->m_color;

parent->m_color=BLACK;

if(uncle_left)

{

uncle_left->m_color=BLACK;

}

rotate_right( uncle , parent);

if (!uncle->parent)

{

node->root=uncle;

}

return ;

}

else

{

uncle->m_color=RED;

uncle_right->m_color=BLACK;

rotate_left( uncle ,uncle_right);

uncle=parent->left;

uncle_left=uncle->left;

uncle->m_color=parent->m_color;

parent->m_color=BLACK;

uncle_left->m_color=BLACK;

rotate_right( uncle , parent);

if (!uncle->parent)

{

node->root=uncle;

}

return ;

}

}

}

}

}

}

}

void delete (wrapdata *node ,int data)

{

redblack * drop;

redblack *suc;

redblack *curnode;

int value;

int mode;

if ( drop=find ( node->root ,data))

{

printf("will delete %d \n",data);

if(!drop->left && !drop->right )

{

if (!drop->parent)

{

myfree(drop);

node->root=0;

}

else

{

if (drop->parent->left==drop)

{

drop->parent->left=0;

}

else

{

drop->parent->right=0;

}

myfree (drop);

}

}

else if (!drop->right )

{

if(!drop ->parent)

{

node->root=drop->left;

}

else

{

if (drop->parent->left==drop)

{

drop->parent->left=drop->left;

mode=0;

}

else

{

drop->parent->right=drop->left;

mode=1;

}

}

curnode=drop->left;

curnode->parent=drop->parent;

myfree (drop);

delete_fixup (node, curnode,mode);

}

else

{

suc=next ( drop->right);

value=drop->m_data;

drop->m_data=suc->m_data;

suc->m_data=value;

if(suc->parent->left==suc)

{

mode=0;

}

else

{

mode=1;

}

if(!suc->right)

{

if(0==mode)

{

suc->parent->left=0;

}

else

{

suc->parent->right=0;

}

myfree(suc);

}

else

{

if(0==mode)

{

suc->parent->left=suc->right;

}

else

{

suc->parent->right=suc->right;

}

curnode=suc->right;

curnode->parent=suc->parent;

myfree(suc);

delete_fixup (node ,curnode,mode);

}

}

node->size--;

}

else

{

}

node->root->m_color=BLACK;

}

void insert ( wrapdata *node , int data )

{

redblack *newnode;

redblack *curnode;

int relation;

node->size++;

newnode=newstruct (data);

printf("will insert %x %d \n",newnode,data);

if ( ! node->root)

{

node->root= newnode;

}

else

{

curnode=node->root;

while(1)

{

relation=compare(data,curnode);

if(relation==-1)

{

node->size--;

myfree(newnode);

return ;

}

else

{

if ( relation==1)

{

if (!curnode->right)

{

curnode->right=newnode;

newnode->parent=curnode;

break;

}

else

{

curnode=curnode->right;

}

}

else

{

if (!curnode->left)

{

curnode->left=newnode;

newnode->parent=curnode;

break;

}

else

{

curnode=curnode->left;

}

}

}

}

insert_fixup ( node , newnode);

}

node->root->m_color=BLACK;

}

int main()

{

int i;

wrapdata *node;

data *newdata;

int count;

init();

srand(time(NULL));

node=(wrapdata*)calloc (1 ,sizeof (wrapdata));

global_node=node;

/*

int value[]={12,24,25,9,4,91,2,100,98,95,93,96,99,120,13};

// int value[]={12,24,25,9,4,91,2};

node=(wrapdata*)calloc (1 ,sizeof (wrapdata));

for (i=0;i<sizeof (value)/sizeof(int );i++)

{

insert (node ,value[i]);

}

printf("%d \n",depth (node->root));

mid_print (node->root,0);

printf("\n");

while(1)

{

printf("into delete mode\n");

while( scanf("%d",&i) && i)

{

delete (node ,i);

printf("%d \n",depth (node->root));

mid_print (node->root,0);

printf("\n");

}

printf("into insert mode\n");

while( scanf("%d",&i) && i)

{

insert (node ,i);

printf("%d \n",depth (node->root));

mid_print (node->root,0);

printf("\n");

}

}

*/

while(1)

{

// printf("into insert mode\n");

while( node->size< COUNT)

{

i=rand()%RAND;

insert (node ,i);

count=check(node->root);

if(count)

{

// printf("\ncheck error\n");

mid_print(node->root,0);

return ;

}

count=mid_print (node->root,0);

if(count!=node->size)

{

// printf("\n %d %d \n",count ,node->size);

return ;

}

if(error_label)

{

return ;

}

if(node->size==COUNT*2/3)

{

printf("%d %d \n",node->size,depth (node->root));

}

}

// printf("into delete mode\n");

while( node->size> COUNT/2)

{

i=rand()%RAND;

delete (node ,i);

count=check(node->root);

if(count)

{

// printf("\ncheck error\n");

return ;

}

count=mid_print (node->root,0);

if(count!=node->size)

{

// printf("\n delete error %d %d \n",count ,node->size);

return ;

}

if(error_label)

{

return ;

}

if(node->size==COUNT*2/3)

{

printf("%d %d \n",node->size,depth (node->root));

}

}

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐