红黑树

来源:互联网 发布:淘宝组装电脑靠谱吗 编辑:程序博客网 时间:2024/06/03 17:17

根据《算法导论》的伪代码写成。最大的收获是,开始写程序前,一定要准备好一个好的数据架构和算法,后面要做的就变得非常非常简单。《算法导论》的伪代码简洁且强壮,边界情况处理的很完美。在写完树和结点的两个结构体以后,后面基本上就是照抄了……

程序不足之处在于没有释放掉malloc的内存。赶时间……

#include <stdio.h>#include <sys/time.h>#include <math.h>#include <malloc.h>#define RED 0#define BLACK 1#define SIZE 7#define RANDOM_MAX 10#define N_LEN sizeof(RBT_NODE)#define T_LEN sizeof(RB_TREE)typedef struct rbt_node{int key;int colour;struct rbt_node* left;struct rbt_node* right;struct rbt_node* parent;}RBT_NODE;typedef struct rb_tree{RBT_NODE* root;RBT_NODE* nil;}RB_TREE;void rb_insert(RB_TREE* T, RBT_NODE* x);void rb_insert_fixup(RB_TREE* T, RBT_NODE* x);void left_rotate(RB_TREE* T, RBT_NODE* x);void right_rotate(RB_TREE* T, RBT_NODE* x);void pre_order_traverse(RB_TREE* T, RBT_NODE* x);void rb_transplant(RB_TREE* T, RBT_NODE* u, RBT_NODE* v);void rb_delete(RB_TREE* T, RBT_NODE* z);void rb_delete_fixup(RB_TREE* T, RBT_NODE* x);RBT_NODE* tree_minimum(RB_TREE* T, RBT_NODE* x);RBT_NODE* search(RB_TREE* T, RBT_NODE* x, int key);int main(){int i,j;int flag ;int a_random[SIZE];int choice;int newnode;RBT_NODE* deletenode;int d;RB_TREE* tree;RBT_NODE* root;RBT_NODE* nil;RBT_NODE* new_node;printf("=======================================================\n");printf("Generate a random array including %d elements :\n", SIZE);srand((int)time(0));for(i=0; i<SIZE; i++){a_random[i] = rand()%RANDOM_MAX;flag = 0;while(flag == 0)//avoid repetition{if(i == 0)break;for(j=0; j<i; j++){if(a_random[i] == a_random[j]){a_random[i] = rand()%RANDOM_MAX;flag = 0;break;}flag = 1;}}printf("%3d ", a_random[i]);}printf("\n=======================================================");printf("\n");nil = (RBT_NODE*)malloc(N_LEN);nil->key = 0;nil->colour = BLACK;root = (RBT_NODE*)malloc(N_LEN);root = nil;root->left = nil;root->right = nil;root->parent = nil;tree = (RB_TREE*)malloc(T_LEN);tree->nil = nil;tree->root = root;//for testint b_random[10]={0,3,2,4,6,5,1};//insert arraryprintf("The red-black tree is:");for(i=0; i<SIZE; i++){new_node = (RBT_NODE*)malloc(N_LEN);new_node->key = b_random[i];rb_insert(tree, new_node);}//show the treepre_order_traverse(tree,tree->root);printf("\n=======================================================\n");//user choiceCHOICE:printf("You can :\n");printf("1. regenerate a red-black tree.\n");printf("2. insert a new node.\n");printf("3. delete a node in the tree.\n");printf("4. exit.\n");printf("Please tell me your choice:\n");scanf("%d", &choice);while(choice!=1 && choice!=2 && choice!=3 && choice!=4){printf("Please input the right number :\n");scanf("%d", &choice);}switch(choice){case 1:{}break;case 2:{printf("Please input your new node key:\n");scanf("%d", &newnode);new_node = (RBT_NODE*)malloc(N_LEN);new_node->key = newnode;rb_insert(tree, new_node);}break;case 3:{printf("Which one do you want to delete:\n");scanf("%d", &d);deletenode = search(tree, tree->root, d);rb_delete(tree, deletenode);}break;case 4:{printf("Thank you!\n");return;}break;}printf("The new red-black tree: \n");pre_order_traverse(tree, tree->root);printf("\n");goto CHOICE;return 0;}/********************************************************/void rb_insert(RB_TREE* T, RBT_NODE* x){RBT_NODE* y;RBT_NODE* z;y = T->nil;z = T->root;while(z != T->nil){y = z;if(x->key <= z->key)z = z->left;elsez = z->right;}x->parent = y;if(y == T->nil)T->root = x;else if(x->key < y->key)y->left = x;else y->right = x;x->left = T->nil;x->right = T->nil;x->colour = RED;rb_insert_fixup(T, x);//for test//printf("\ntest:\n");//pre_order_traverse(T, T->root);//printf("\n");return;/*RBT_NODE *ins;RBT_NODE *temp;ins = T->root;if(T->root == T->nil){x->left = T->nil;x->right = T->nil;x->parent = T->nil;x->colour =  BLACK;T->root = x;return;}//printf("\n %3d %3d \n", T->key,x->key);while(1){temp = ins;if((x->key) <= (ins->key)){ins = ins->left;if(ins == T->nil){temp->left = x;x->parent = temp;break;}}else {ins = ins->right;if(ins == T->nil){temp->right = x;x->parent = temp;break;}}}x->left = T->nil;x->right = T->nil;x->colour =  RED;rb_insert_fixup(T,x);printf("\ntest:\n");pre_order_traverse(T, T->root);printf("\n");return ;*/}void pre_order_traverse(RB_TREE* T, RBT_NODE* x){if(T->root == T->nil)return;if(x == T->nil)return;printf("\nThe key is%3d, ",x->key);if(x->colour == 0)printf("  red, ");elseprintf("black, ");if(x->left == T->nil)printf("left is NIL, ");elseprintf("left is %3d, ", x->left->key);if(x->right == T->nil)printf("right is NIL, ");elseprintf("right is %3d, ", x->right->key);if(x->parent == T->nil)printf("parent is NIL, ");elseprintf("parent is %3d, ", x->parent->key);pre_order_traverse(T, x->left);pre_order_traverse(T, x->right);return;}void left_rotate(RB_TREE* T, RBT_NODE*x){RBT_NODE* y;y = x->right;x->right = y->left;if(y->left != T->nil)y->left->parent = x;y->parent = x->parent;if(x->parent == T->nil)T->root = y;else if(x == x->parent->left)x->parent->left = y;elsex->parent->right = y;y->left = x;x->parent = y;return;}void right_rotate(RB_TREE* T, RBT_NODE*x){RBT_NODE* y;y = x->left;x->left = y->right;if(y->right != T->nil)y->right->parent = x;y->parent = x->parent;if(x->parent == T->nil)T->root = y;else if(x == x->parent->right)x->parent->right = y;elsex->parent->left = y;y->right = x;x->parent = y;return;}void rb_insert_fixup(RB_TREE* T, RBT_NODE* x){RBT_NODE* y;while(x->parent->colour == RED){if(x->parent == x->parent->parent->left){////////////////if(x->parent->parent->right == T->nil)//{//T->root->colour = BLACK;//break;//}/////////////y = x->parent->parent->right;if(y->colour == RED){x->parent->colour = BLACK;y->colour = BLACK;x->parent->parent->colour = RED;x = x->parent->parent;}else {if(x == x->parent->right){x = x->parent;left_rotate(T,x);}x->parent->colour = BLACK;x->parent->parent->colour =RED;right_rotate(T,x->parent->parent);}}else//exchange left with right{////////////if(x->parent->parent->left != T->nil)//{//T->root->colour = BLACK;//break;//}/////////y = x->parent->parent->left;if(y->colour == RED){x->parent->colour = BLACK;y->colour = BLACK;x->parent->parent->colour = RED;x = x->parent->parent;}else {if(x == x->parent->left){x = x->parent;right_rotate(T,x);}x->parent->colour = BLACK;x->parent->parent->colour = RED;left_rotate(T,x->parent->parent);}}}T->root->colour = BLACK;}RBT_NODE* tree_minimum(RB_TREE* T, RBT_NODE* x){while(x->left != T->nil)x = x->left;return x;}void rb_transplant(RB_TREE* T, RBT_NODE* u, RBT_NODE* v){if(u->parent == T->nil)T->root = v;elseif(u == u->parent->left)u->parent->left = v;else u->parent->right = v;v->parent = u->parent;return;}void rb_delete(RB_TREE* T, RBT_NODE* z){RBT_NODE* x;RBT_NODE* y;RBT_NODE* temp;int y_ori_colour;y = z;y_ori_colour = y->colour;if(z->left == T->nil){x = z->right;rb_transplant(T, z, z->right);}elseif(z->right == T->nil){x = z->left;rb_transplant(T, z, z->left);}else{y = tree_minimum(T, z->right);y_ori_colour = y->colour;x = y->right;if(y->parent == z)x->parent = y;else {rb_transplant(T, y, y->right);y->right = z->right;y->right->parent = y;}rb_transplant(T, z, y);y->left = z->left;y->left->parent = y;y->colour = z->colour;}if(y_ori_colour == BLACK)rb_delete_fixup(T, x);}void rb_delete_fixup(RB_TREE* T, RBT_NODE* x){RBT_NODE* w;while( (x != T->root) && (x->colour == BLACK)){if(x == x->parent->left){w = x->parent->right;if(w->colour == RED){w->colour = BLACK;x->parent->colour = RED;left_rotate(T, x->parent);w = x->parent->right;}if( (w->left->colour == BLACK) && (w->right->colour == BLACK) ){w->colour = RED;x = x->parent;}else{if(w->right->colour == BLACK){w->left->colour = BLACK;w->colour = RED;right_rotate(T, w);w = x->parent->right;}w->colour = x->parent->colour;x->parent->colour = BLACK;w->right->colour = BLACK;left_rotate(T, x->parent);x = T->root;}}else//exchange left with right{w = x->parent->left;if(w->colour == RED){w->colour = BLACK;x->parent->colour = RED;right_rotate(T, x->parent);w = x->parent->left;}if( (w->right->colour == BLACK) && (w->left->colour == BLACK) ){w->colour = RED;x = x->parent;}else{if(w->left->colour == BLACK){w->right->colour = BLACK;w->colour = RED;left_rotate(T, w);w = x->parent->left;}w->colour = x->parent->colour;x->parent->colour = BLACK;w->left->colour = BLACK;right_rotate(T, x->parent);x = T->root;}}}x->colour =BLACK;return;}RBT_NODE* search(RB_TREE* T, RBT_NODE* x, int key){if((x == T->nil) || (key == x->key))return x;if(key < x->key)return search(T, x->left, key);else return search(T, x->right, key);}


0 0
原创粉丝点击