算法导论 红黑树的扩张 动态顺序统计

来源:互联网 发布:淘宝聘用店主 编辑:程序博客网 时间:2024/06/10 04:51
#include <stdio.h>    #include <stdlib.h>    #define RED 1    #define BLACK 0        typedef struct RBTreeNode    {        int key;        int color; int size;    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; nil->size=0;}        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;   //维护子树数目y->size=x->size;x->size=x->left->size+x->right->size+1;}        void rightRotate(pRBT *root,pRBT x)    {        //右旋要有左子树        if(x->left==nil)            return;        pRBT y=x->left;        x->left=y->right;if(y->right != nil)            y->right->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->right=x;        x->p=y;   //维护子树数目x->size=y->size;y->size=y->left->size+y->right->size+1;}        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;z->size=1;    pRBT x=(*root);        pRBT y=nil;        while(x != nil)        {    x->size++;//从根下降过程中,增加路径上所有子树数目        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;      else          u->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->p,x;//新增一段回溯到根的迭代,减少路径上每个结点的子树数目while(y){y->size--;y=y->p;}    y=z;      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 ","黑");          else              printf("%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;          else              x=x->right;      }      return x;  }  pRBT at(pRBT root,int i){if(root==nil)return nil;pRBT x=root;int r=x->left->size+1;if(i==r)return x;else if(i<r)return at(x->left,i);elsereturn at(x->right,i-r);}int getIndex(pRBT root,pRBT x){int r=x->left->size+1;pRBT y=x;while(y != root){if(y==y->p->right)r=r+y->p->left->size+1;y=y->p;}return r;}  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);      pRBT x=at(root,3);printf("%d\n",x->key);int r=getIndex(root,x);printf("%d\n",r);    getchar();  } 

原创粉丝点击