構造區間樹。以及區間樹查詢演算法實現。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; }
效果圖: