红黑树的C实现

来源:互联网 发布:门诊系统的数据库设计 编辑:程序博客网 时间:2024/06/05 20:20

看了nginx的源码,其中的定时器采用的数据结构是红黑树,而linux内核中高级数据结构也采用了红黑树,由此可见红黑树效率确实很高。

红黑树是一种局部平衡树,不像AV树那样绝对平衡。但是实现起来也比较复杂,鄙人水平有限,在了解了红黑树原理之后自己用C实现了

红黑树,花了一天时间调试才通过,建议大家也写写,有得地方注释不够清楚,下次补充。


一般的,红黑树,满足以下性质,即只有满足以下全部性质的树,我们才称之为红黑树:
 1)每个结点要么是红的,要么是黑的。
 2)根结点是黑的。
 3)每个叶结点,即空结点(NIL)是黑的。
 4)如果一个结点是红的,那么它的俩个儿子都是黑的。
 5)对每个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点

#include <stdlib.h>#include <stdio.h>#include <string.h>#define RED 1#define BLOCK 0//瀹氫箟鑺傜偣typedef struct myrbtree{int key;   //鑺傜偣鍏抽敭瀛楋紝鐢ㄤ互鍞竴鏍囪瘑涓€涓妭鐐�struct myrbtree *parent,*left,*right;int color;  //绾㈤粦灞炴€�}Rbnode,*Rbpoint;Rbpoint sentinel ;  //鍝ㄥ叺锛屾墍鏈夌殑鍙跺瓙鑺傜偣鎸囧悜鍝ㄥ叺Rbpoint createnode(int key)  //鍒涘缓涓€涓┖鑺傜偣{Rbpoint new = (Rbpoint)malloc(sizeof(Rbnode));new->key = key;new->parent = sentinel;new->left = sentinel;new->right = sentinel;new->color = RED;return new;}//涓牴閬嶅巻浜屽樊鏍戝嚱鏁�static void firstroot(Rbpoint root){Rbpoint tmp = root;if(tmp->left != sentinel){firstroot(tmp->left);}printf("%d,",tmp->key);if(tmp->right != sentinel){firstroot(tmp->right);}}//鍒涘缓鏍硅妭鐐瑰嚱鏁�Rbpoint createroot(int key){Rbpoint root = createnode(key);root->color = BLOCK; //鏍硅妭鐐瑰畾涔変负榛戣壊}Rbpoint rbbalance(Rbpoint ,Rbpoint );  Rbpoint leftrobate(Rbpoint ,Rbpoint);Rbpoint rightrobate(Rbpoint ,Rbpoint);Rbpoint rbinsert(Rbpoint root,Rbpoint new)  //鎻掑叆涓€涓妭鐐癸紝root涓烘牴,new涓烘柊鎻掑叆鑺傜偣{if(root->color != BLOCK){printf("root not BLOCK\n");exit(0);}if(root == sentinel)return new;Rbpoint tmp = root;while(tmp != sentinel) //绾㈤粦鏍戞槸鎺掑簭鏍戯紝鏂拌妭鐐规彃鍏ュ埌鏍戜腑骞舵帓搴�{if(new->key > tmp->key){if(tmp->right == sentinel) //澶т簬褰撳墠鑺傜偣锛屽垯寰€鍙虫煡鎵剧┖浣嶆彃鍏�{tmp->right = new;new->parent = tmp;break;}elsetmp = tmp->right;}else     //灏忎簬褰撳墠鑺傜偣锛屽線宸︽煡鎵剧┖浣嶆彃鍏�{if(tmp->left == sentinel){tmp->left = new;new->parent = tmp;break;}elsetmp = tmp->left;}}root = rbbalance(root,new);  //鎻掑叆涔嬪悗闇€瑕佸钩琛★紝閫氳繃绉诲姩锛岀炕杞互婊¤冻绾㈤粦鏍戞潯浠�return root;}Rbpoint leftrobate(Rbpoint root,Rbpoint new)  //宸︾炕杞�{Rbpoint tmp;if(new == root)return root;tmp = new->parent;if(tmp->parent != sentinel) //缈昏浆鐨勬牴涓烘牴鑺傜偣{if(tmp->parent->left == tmp)tmp->parent->left = new;elsetmp->parent->right = new;new->parent = tmp->parent;tmp->right = new->left;new->left->parent = tmp;tmp->parent = new;new->color = BLOCK;tmp->color = RED;new->left = tmp;return root;}else          //缈昏浆鐨勬牴涓嶄负鏍硅妭鐐�{new->parent = sentinel;tmp->right = new->left;new->left->parent = tmp;tmp->parent = new;new->color = BLOCK;tmp->color = RED;new->left = tmp;return new;}}Rbpoint rightrobate(Rbpoint root,Rbpoint new)  //鍙堢炕杞紝缈昏浆杩囩▼涓庡乏缈昏浆绫讳技{Rbpoint tmp;tmp = new->parent;if(tmp->parent != sentinel){if(tmp->parent->right == tmp)tmp->parent->right = new;elsetmp->parent->left = new;new->parent = tmp->parent;tmp->left = new->right;new->right->parent = tmp;tmp->parent = new;new->color = BLOCK;tmp->color = RED;new->right = tmp;return root;}else{new->parent = sentinel;tmp->left = new->right;new->right->parent = tmp;new->color = BLOCK;tmp->color = RED;new->right = tmp;tmp->parent = new;return new;}}Rbpoint rbbalance(Rbpoint root,Rbpoint new)  //瀵逛簩鎿︽爲杩涜骞宠 鍖�{Rbpoint tmp;if(new == root)return root;if(new->parent->color == BLOCK)return root;if((new->parent->parent->left != sentinel)&&(new->parent->parent->right != sentinel)&&(new->parent->parent->left->color == RED)&&(new->parent->parent->right->color == RED)){new->parent->parent->left->color = BLOCK;new->parent->parent->right->color = BLOCK;if(new->parent->parent == root){root->color = BLOCK;return  root;}new->parent->parent->color = RED;tmp = new->parent->parent;rbbalance(root,tmp);}else if((new->parent->left == new)&&(new->parent->parent->left == new->parent)){return rightrobate(root,new->parent);}else if((new->parent->right == new)&&(new->parent->parent->right== new->parent)){return leftrobate(root,new->parent);}else if((new->parent->right == new)&&(new->parent->parent->left == new->parent)){root = leftrobate(root,new);return rightrobate(root,new);}else if((new->parent->left==new)&&(new->parent->parent->right == new->parent)){root = rightrobate(root,new);return leftrobate(root,new);}}Rbpoint rbfind(Rbpoint root,int key)  //閫氳繃閿煡鎵炬爲涓殑鑺傜偣{Rbpoint tmp = root;while(tmp->key != key){if(tmp->key > key){tmp = tmp->left;continue;}else{tmp = tmp->right;continue;}}return tmp;}Rbpoint findmin(Rbpoint root,Rbpoint right)   //鏌ユ壘鏍戜腑鐨勬渶灏忚妭鐐�{if(right == sentinel)return root;Rbpoint tmp = right;while(tmp->left != sentinel)tmp = tmp->left;return tmp;}Rbpoint freenode(Rbpoint root,Rbpoint node)   //閲婃斁涓€涓妭鐐�{if(node->parent == root)node->parent->right = node->right;else if(node->key > node->parent->key)node->parent->right = node->right;elsenode->parent->left = node->right;if(node->right != sentinel)node->right->parent = node->parent;free(node);}Rbpoint rbdelete(Rbpoint root,int key)   //鍒犻櫎涓€涓妭鐐�{Rbpoint delz = rbfind(root,key);if((delz == root)&&(delz->left == delz->right)){free(root);return sentinel;}Rbpoint tmpy = findmin(delz,delz->right);Rbpoint tmpx;if(tmpy != delz)tmpx = tmpy->right;else  {tmpy->right = tmpy->left;tmpy->left = sentinel;tmpx = tmpy->right;}delz->key = tmpy->key;        tmpy->key = key;Rbpoint tmp = tmpy->parent;if(tmpy->color == RED){freenode(delz,tmpy);return root;}freenode(delz,tmpy);if((tmpx!=sentinel)&&(tmpx->color == RED)){tmpx->color = BLOCK;return root;}int flag = 1,color;Rbpoint tmpw ;Rbpoint tmpp ;while(flag){       if(((tmpx == sentinel)&&(tmpx == tmp->left))||((tmpx != sentinel)&&(tmpx->key < tmpx->parent->key))){if(tmpx == sentinel)                {                        tmpw = tmp->right;                        tmpp = tmp;                }else{tmpw = tmpx->parent->right;        tmpp = tmpx->parent;}if(tmpw->color == RED){tmpw->color = BLOCK;tmpp->color = RED;root = leftrobate(root,tmpw);continue;}if((tmpw->color == BLOCK)&&(tmpw->right!=sentinel)&&(tmpw->right->color == RED)){color = tmpw->color;tmpw->color = tmpp->color;tmpp->color = color;tmpw->right->color = BLOCK;root = leftrobate(root,tmpw);return root;}if((tmpw->color == BLOCK)&&(tmpw->left!=sentinel)&&(tmpw->left->color==RED)&&(tmpw->right!=sentinel)&&(tmpw->right->color==BLOCK)){color = tmpw->color;tmpw->color = tmpw->left->color;tmpw->left->color = color;root  = rightrobate(root,tmpw->left);continue;}if(tmpw->color == BLOCK){tmpw->color = RED;if(tmpp->color == RED){tmpp->color = BLOCK;return root;}if(tmpp->parent == sentinel)return root;tmpx = tmpw->parent;continue;}}else{if(tmpx != sentinel){tmpw = tmpx->parent->left;        tmpp = tmpx->parent;}else{tmpw = tmp->left;tmpp = tmp;}if(tmpw->color == RED){tmpw->color = BLOCK;tmpp->color = RED;root = rightrobate(root,tmpw);continue;}if((tmpw->color == BLOCK)&&(tmpw->left!=sentinel)&&(tmpw->left->color == RED)){color = tmpw->color;tmpw->color = tmpp->color;tmpp->color = color;tmpw->left->color = BLOCK;root = rightrobate(root,tmpw);return root;}if((tmpw->color == BLOCK)&&(tmpw->left!=sentinel)&&(tmpw->left->color==BLOCK)&&(tmpw->right!=sentinel)&&(tmpw->right->color==RED)){color = tmpw->color;tmpw->color = tmpw->right->color;tmpw->right->color = color;root = leftrobate(root,tmpw->right);continue;}if(tmpw->color == BLOCK){tmpw->color = RED;if(tmpp->color == RED){tmpp->color = BLOCK;return root;}if(tmpp->parent == sentinel)return root;tmpx = tmpw->parent;continue;}}}}void  testpc(Rbpoint root,Rbpoint test){if(test == root)return ;if(test->key > test->parent->key){if(test->parent->right != test){printf("insert err %d\n",test->key);exit(0);}}else{if(test->parent->left != test){printf("insert err %d\n",test->key);exit(0);}}}void midroot(Rbpoint root)   //鍏堟牴閬嶅巻{if(root!=sentinel)printf("%d(%d),",root->key,root->color);if(root->left!=sentinel)midroot(root->left);if(root->right!=sentinel)midroot(root->right);//printf("\n");}int main(int argc,char **argv){        sentinel = (Rbpoint)malloc(sizeof(Rbnode));printf("test createnode...\n");Rbpoint root = createroot(1);printf("test.key:%d,test.color:%d\n***************\n",root->key,root->color);printf("test insert....\n");Rbpoint test = createnode(2);root = rbinsert(root,test);int keytest[10000];int i;for(i=5;i<1000;i++){test = createnode(i);root = rbinsert(root,test);testpc(root,test);}firstroot(root);midroot(root);printf("test firstroot done:.....\n");for(i=10;i<450;i++){root = rbdelete(root,i);firstroot(root);printf("\n");midroot(root);printf("\n");}printf("test firstroot:.....\n");}


0 0