1. 程式人生 > >構造區間樹。以及區間樹查詢演算法實現。C語言實現

構造區間樹。以及區間樹查詢演算法實現。C語言實現

//左旋右旋也需要維護區間性質 void leftRotate(Tnode* root,Tnode x){     Tnode y = x->r;     x->r = y->l;     //y->l = x;     if(y->l!=tnil)     (y->l)->p = x;     y->p = x->p;     if(x==*root){        *root = y;     }else{        if(x==(x->p)->l){           (x->p)->l = y;        }else if(x==(x->p)->r){            (x->p)->r = y;        }     }     y->l = x;     x->p = y;     //維護區間性質只需要處理x.max和y.max即可     x->max = Max(x->tint.high,x->l->max,x->r->max);     y->max = Max(y->tint.high,y->l->max,y->r->max); } void rightRotate(Tnode* root,Tnode y){      Tnode x = y->l;      y->l = x->r;      if(x->r!=tnil){        (x->r)->p = y;      }      x->p = y->p;      if(y==*root){         *root = x;      }else{          if(y==(y->p)->r){             (y->p)->r = x;          }else{             (y->p)->l = x;          }      }      x->r = y;      y->p = x;      //維護區間性質只需要處理x.max和y.max即可     x->max = Max(x->tint.high,x->l->max,x->r->max);     y->max = Max(y->tint.high,y->l->max,y->r->max); } void fixUp(Tnode* root,Tnode z){         while((z->p)->color==1){         if(z->p==((z->p)->p)->l){            //情況1:叔節點為紅色             Tnode y = ((z->p)->p)->r;             if(y->color==1){                 (z->p)->color = 0;                  y->color = 0;                  z = ((z->p)->p);                  z->color = 1;             }else{                 //2                 if(z==(z->p)->r){                    z = z->p;                    //進行左旋。轉化為情況3                    leftRotate(root,z);                 }                 //3                 (z->p)->color = 0;                 ((z->p)->p)->color = 1;                 rightRotate(root,(z->p)->p);             }         }else{             //對稱處理             Tnode y = ((z->p)->p)->l;             //情況4             if(y->color==1){               (z->p)->color = 0;               y->color = 0;               z = ((z->p)->p);               z->color = 1;             }else{                 //5                 if(z==(z->p)->l){                    z = z->p;                    rightRotate(root,z);                 }                (z->p)->color = 0;                ((z->p)->p)->color = 1;                leftRotate(root,(z->p)->p);             }         }         }     (*root)->color = 0; } void insertTnode(Tnode* root,int key,TINT tint){     //區間樹在插入的時候要進行維護     Tnode z = (Tnode)malloc(sizeof(struct tnode));     Tnode temp = *root;     Tnode temp1 = temp;     if(*root==NULL){        *root = z;        temp1 = tnil;     }else{         while(temp!=tnil){             //需要將經過的路徑如果max不滿足。則需要修正             if(temp->max<tint.high){                 temp->max = tint.high;             }             if(tint.low>temp->tint.low){                 temp1 = temp;                 temp = temp->r;             }else{                 temp1 = temp;                 temp = temp->l;             }         }         if(tint.low>temp1->tint.low){            temp1->r = z;         }else{            temp1->l = z;         }     }     z->p = temp1;     z->r = tnil;     z->l = tnil;     z->key = key;     z->color = 1;//設定為紅色。以保證不會違反性質5     z->max = tint.high;//新插入節點的max為tint的high     z->tint = tint;//區間     fixUp(root,z); } //判斷是否區間重疊 int judgeOverlap(TINT x,TINT y){     //判斷不重疊。取補     if(x.high<y.low||y.high<x.low){        return false;     }     return true;

} Tnode intervalSearch(Tnode t,TINT i){      Tnode x = t;      while(x!=tnil&&!judgeOverlap(x->tint,i)){          if(x->l->max>=i.low){             x = x->l;          }else{            x = x->r;          }      }      return x; }

效果圖: