算法导论 红黑树(附带黑高度)

来源:互联网 发布:国际象棋软件哪个好 编辑:程序博客网 时间:2024/05/22 06:03
#include <stdio.h>  #include <stdlib.h>  #define RED 1  #define BLACK 0    typedef struct RBTreeNode  {      int key;      int color;      RBTreeNode *p;      RBTreeNode *left;      RBTreeNode *right;  }RBT,*pRBT;    pRBT nil=(pRBT)malloc(sizeof(RBT));  int bh=0;void initNil()  {      nil->key=-1;      nil->color=BLACK;      nil->p=NULL;      nil->left=NULL;      nil->right=NULL;  }    void leftRotate(pRBT *root,pRBT x)  {      //左旋要有右子树      if(x->right==nil)          return;      pRBT y=x->right;      x->right=y->left;      if(y->left != nil)          y->left->p=x;      y->p=x->p;      if(x->p==nil)      {          (*root)=y;      }      else if(x == x->p->left)      {          x->p->left=y;      }      else      {          x->p->right=y;      }      y->left=x;      x->p=y;  }    void rightRotate(pRBT *root,pRBT y)  {      //右旋要有左子树      if(y->left==nil)          return;      pRBT x=y->left;      y->left=x->right;      x->p=y->p;  if(x->right != nil)x->right->p=y;    if(y->p==nil)      {          (*root)=x;      }      else if(y==y->p->left)      {          y->p->left=x;      }      else      {          y->p->right=x;      }      x->right=y;      y->p=x;  }    void rbInsertFixup(pRBT *root,pRBT z)  {      while(z->p->color==RED)      {          if(z->p==z->p->p->left)          {              pRBT y=z->p->p->right;              if(y->color==RED)              {                  z->p->color=BLACK;                  y->color=BLACK;                  z->p->p->color=RED;                  z=z->p->p;              }              else               {                  if(z==z->p->right)                  {                      z=z->p;                      leftRotate(root,z);                  }                  z->p->color=BLACK;                  z->p->p->color=RED;                  rightRotate(root,z->p->p);              }          }          else          {              pRBT y=z->p->p->left;              if(y->color==RED)              {                  z->p->color=BLACK;                  y->color=BLACK;                  z->p->p->color=RED;                  z=z->p->p;              }              else               {                  if(z==z->p->left)                  {                      z=z->p;                      rightRotate(root,z);                  }                  z->p->color=BLACK;                  z->p->p->color=RED;                  leftRotate(root,z->p->p);              }          }      }  if((*root)==nil || (*root)->color==RED)bh++;(*root)->color=BLACK;}    void rbInsert(pRBT *root,int key)  {      pRBT z=(pRBT)malloc(sizeof(RBT));      z->key=key;      pRBT x=(*root);      pRBT y=nil;      while(x != nil)      {          y=x;          if(z->key<x->key)          {              x=x->left;          }          else          {              x=x->right;          }      }      z->p=y;      if(y==nil)      {          (*root)=z;      }      else if(z->key<y->key)      {          y->left=z;      }      else      {          y->right=z;      }      z->left=nil;      z->right=nil;      z->color=RED;      rbInsertFixup(root,z);  }void rbTransplant(pRBT *root,pRBT u,pRBT v){if(u->p==nil)(*root)=v;else if(u==u->p->left)u->p->left=v;elseu->p->right=v;v->p=u->p;}pRBT treeMinimum(pRBT root){if(root==nil)return root;pRBT x=root;while(x->left!=nil){x=x->left;}return x;}void rbDeleteFixup(pRBT *root,pRBT x){while(x != *root && x->color==BLACK){if(x==x->p->left){pRBT w=x->p->right;if(w->color==RED){w->color=BLACK;x->p->color=RED;leftRotate(root,x->p);w=x->p->right;}if(w->left->color==BLACK && w->right->color==BLACK){w->color=RED;x=x->p;if(x==*root)bh--;}else{if(w->right->color == BLACK){w->left->color=BLACK;w->color=RED;rightRotate(root,w);w=x->p->right;}w->color=x->p->color;x->p->color=BLACK;w->right->color=BLACK;leftRotate(root,x->p);x=(*root);}}else{pRBT w=x->p->left;if(w->color==RED){w->color=BLACK;x->p->color=RED;rightRotate(root,x->p);w=x->p->left;}if(w->left->color==BLACK && w->right->color==BLACK){w->color=RED;x=x->p;}else{if(w->left->color == BLACK){w->right->color=BLACK;w->color=RED;leftRotate(root,w);w=x->p->left;}w->color=x->p->color;x->p->color=BLACK;w->left->color=BLACK;rightRotate(root,x->p);x=(*root);}}}x->color=BLACK;}void rbDelete(pRBT *root,pRBT z){pRBT y=z,x;int yOrigColor=y->color;if(z->left==nil){x=z->right;rbTransplant(root,z,x);}else if(z->right==nil){x=z->left;rbTransplant(root,z,x);}else{y=treeMinimum(z->right);yOrigColor=y->color;x=y->right;if(y->p==z){x->p=y;}else{rbTransplant(root,y,x);y->right=z->right;y->right->p=y;}rbTransplant(root,z,y);y->left=z->left;y->left->p=y;y->color=z->color;if(yOrigColor==BLACK)rbDeleteFixup(root,x);}}void preTrav(pRBT root,char c){if(root==nil)return;else{printf("%d ",root->key);if(root->color==BLACK)printf("%s ","黑");elseprintf("%s ","红");printf("%c ",c);preTrav(root->left,'L');preTrav(root->right,'R');}}pRBT treeSearch(pRBT root,int key){pRBT x=root;while(x!=nil && x->key!=key){if(key<x->key)x=x->left;elsex=x->right;}return x;}void main(){initNil();pRBT root=nil;rbInsert(&root,100);rbInsert(&root,80);rbInsert(&root,90);rbInsert(&root,70);rbInsert(&root,10);rbInsert(&root,20);rbInsert(&root,30);rbInsert(&root,50);rbInsert(&root,60);rbInsert(&root,40);preTrav(root,'M');printf("\n");printf("bh:%d\n",bh);pRBT x=treeSearch(root,50);rbDelete(&root,x);preTrav(root,'M');printf("\n");printf("bh:%d\n",bh);rbInsert(&root,50);preTrav(root,'M');printf("\n");printf("bh:%d\n",bh);x=treeSearch(root,70);rbDelete(&root,x);preTrav(root,'M');printf("\n");printf("bh:%d\n",bh);x=treeSearch(root,20);rbDelete(&root,x);preTrav(root,'M');printf("\n");printf("bh:%d\n",bh);getchar();}

0 0
原创粉丝点击