算法导论 第十四章:区间树
来源:互联网 发布:广联达软件配置要求 编辑:程序博客网 时间:2024/05/22 07:43
区间树是一种对动态集合进行维护的红黑树,具体设计如下:
step1:基础数据结构
我们选择的基础数据结构式红黑树,其中每个节点x包含一个区间域x.int,x的关键字为区间的低端点 x.int.low.
step2:附加信息
每个节点x除了区间信息外,还包含一个值x.max,即以x为根的的子树中所有区间的断点的最大值
step3:对信息维护
必须验证对含有n个节点的区间树的插入和删除都能在O(lgn)时间内完成,给定区间x.int 和 x.max 则有:x.max = max(x.int.high,x.left.max,x.right.max)
step4:设计新的操作
我们唯一需要的新操作是INTERVAL-SEARCH(T,i),用以找出树T中覆盖区间i的那个节点。伪代码如下:
运行时间:O(lgn).
构建的区间树可以表示成如下:
完整代码如下:
#include<iostream>#include<iomanip>using namespace std;#define BLACK 0#define RED 1typedef struct interval{int low;int high;}interval;typedef struct IntervalTNode{int key;bool color;IntervalTNode *parent;IntervalTNode *left;IntervalTNode *right;interval inte; //additional informationint max; //additional information}IntervalTNode;typedef struct IntervalTree{IntervalTNode *root;}IntervalTree;//init sentine NILinterval interval0={-1,-1};IntervalTNode NILL={-1,BLACK,NULL,NULL,NULL,interval0,-1};IntervalTNode *NIL=&NILL; /*-----------------------------------------------------------------------*/int Max(int a,int b,int c){if(a>b)return a>c ? a:c;elsereturn b>c ? b:c;}bool Overlap(interval a,interval b){if(a.high < b.low || a.low > b.high) // a & b do not overlapreturn 0;return 1;}IntervalTNode *IntervalT_Search(IntervalTree *T,interval i){IntervalTNode *x=T->root;while(x!=NIL && !Overlap(i,x->inte)){ if(x->left !=NIL && x->left->max>= i.low)x=x->left;elsex=x->right;}return x;}/*-----------------------------------------------------------------------*/void IntervalT_InorderWalk(IntervalTNode *x){if(x!=NIL) { IntervalT_InorderWalk(x->left);cout<<"["<<setw(3)<<x->inte.low<<setw(3)<<x->inte.high<<" ]";if(x->color==1)cout<<" Red "<<x->max<<endl;elsecout<<" Black "<<x->max<<endl;IntervalT_InorderWalk(x->right); } }IntervalTNode *IntervalT_Minimum(IntervalTNode *x){while(x->left != NIL)x=x->left;return x;}IntervalTNode *IntervalT_Successor(IntervalTNode *x){ if(x->right != NIL) return IntervalT_Minimum(x->right); IntervalTNode *y = x->parent; while(y != NIL && x == y->right){ x = y; y = y->parent; } return y;}void Left_Rotate(IntervalTree *T,IntervalTNode *x){IntervalTNode *y=x->right; //set yx->right=y->left; //turn y's left subtree into x's right subtreeif(y->left!=NIL)y->left->parent=x;y->parent=x->parent; //link x's parent to y;if(x->parent == NIL)T->root=y;else if(x==x->parent->left)x->parent->left=y;elsex->parent->right=y;y->left=x; //put x on y's leftx->parent=y;//maitaining additional informationy->max=x->max;x->max=Max(x->inte.high,x->left->max,x->right->max);}void Right_Rotate(IntervalTree *T,IntervalTNode *x){IntervalTNode *y=x->left; //set yx->left=y->right; //link x's left tree into y's right subtree;if(y->right !=NIL)y->right->parent=x;y->parent=x->parent; //link x's parent to yif(x->parent == NIL)T->root=y;else if(x == x->parent->left)x->parent->left=y;elsex->parent->right=y;y->right=x; //put x on y's rightx->parent=y;//Maintaining additional informationy->max=x->max;x->max=Max(x->inte.high,x->left->max,x->right->max);}void IntervalT_InsertFixup(IntervalTree *T,IntervalTNode *z){while(z->parent->color==RED){if(z->parent == z->parent->parent->left) {IntervalTNode *y=z->parent->parent->right; if(y->color==RED){ z->parent->color=BLACK; //case 1y->color=BLACK; //case 1z->parent->parent->color=RED; //case 1z=z->parent->parent; //case 1}else{ if(z==z->parent->right){ z=z->parent; //case 2Left_Rotate(T,z); //case 2 }z->parent->color=BLACK; //case 3z->parent->parent->color=RED; //case 3Right_Rotate(T,z->parent->parent); //case 3 } }else{//a me as then clause with "right" and "left" exchanged IntervalTNode *y=z->parent->parent->left;if(y->color==RED){z->parent->color==BLACK;y->color=BLACK;z->parent->parent->color=RED;z=z->parent->parent; }else{if(z==z->parent->left){z=z->parent;Right_Rotate(T,z); }z->parent->color=BLACK;z->parent->parent->color=RED;Left_Rotate(T,z->parent->parent); } } } T->root->color=BLACK; //turn the root to BLACK}void IntervalT_Insert(IntervalTree *T,interval inte){IntervalTNode *z=new IntervalTNode();z->key=inte.low;z->max=inte.high;z->inte=inte;z->color =RED; z->parent=NIL;z->left=NIL;z->right=NIL;IntervalTNode *y=NIL; //y is the parent of xIntervalTNode *x=T->root;while(x != NIL){ x->max=max(x->max,z->max); //Maintaining the max value of each node from z up to rooty=x;if(z->key < x->key)x=x->left;elsex=x->right;} z->parent=y; //link new node's parent node to y(y's child is NIL)if(y==NIL)T->root=z;else if(z->key < y->key)y->left=z;elsey->right =z;IntervalT_InsertFixup(T,z);}void IntervalT_DeleteFixup(IntervalTree *T,IntervalTNode *x){IntervalTNode *w;while(x!=T->root && x->color==BLACK){if(x==x->parent->left) {w=x->parent->right; //set w to x's siblingif(w->color==RED) //case 1:x's sibling w is red{w->color=BLACK;x->parent->color=RED;Left_Rotate(T,x->parent);w=x->parent->right; }if(w->left->color==BLACK && w->right->color==BLACK) { //case 2:x's sibling w is black and both of w's children are blackw->color=RED;x=x->parent;}else{ if(w->right->color==BLACK) {//case 3:x's sibling w is black,w's left child is red, and w's right child is blackw->left->color=BLACK;w->color=RED;Right_Rotate(T,w);w=x->parent->right; }w->color=x->parent->color; //case 4: x's sibling w is black,and w's right child is redx->parent->color=BLACK; //.w->right->color=BLACK; // .Left_Rotate(T,x->parent); // .x=T->root; //case 4}}else{//Same as then clause with "right" and "left" exchangedw=x->parent->left;if(w->color==RED){w->color=BLACK;x->parent->color=RED;Right_Rotate(T,x->parent);w=x->parent->left;} if(w->left->color==BLACK && w->right->color==BLACK){ w->color=RED;x=x->parent;}else{if(w->left->color==BLACK){w->right->color=BLACK;w->color=RED;Left_Rotate(T,w);w=x->parent->left; }w->color=x->parent->color;x->parent->color=BLACK;w->left->color=BLACK;Right_Rotate(T,x->parent);x=T->root; } } } x->color=BLACK;}void IntervalT_Delete(IntervalTree *T,IntervalTNode *z){IntervalTNode *x=NULL,*y=NULL,*g=NULL;if(z->left == NIL || z->right==NIL)y=z;elsey=IntervalT_Successor(z);//maintaining additional informationg=y->parent;g->max=g->inte.high;g=g->parent;while(g->max==y->max){ g->max=Max(g->max,g->left->max,g->right->max);g=g->parent;}//delete y nodeif(y->left !=NIL)x=y->left;elsex=y->right;x->parent=y->parent;if(y->parent==NIL)T->root=x;else if(y==y->parent->left)y->parent->left=x;elsey->parent->right=x;if(y != z)z->key=y->key;if(y->color==BLACK)IntervalT_DeleteFixup(T,x);}int main(){interval A[]={{16,21},{8,9},{25,30},{5,8},{15,23},{17,19},{26,26},{0,3},{6,10},{19,20}};int n=sizeof(A)/sizeof(interval);cout<<"/*---------------------Create Interval Tree-------------------*/"<<endl;IntervalTree *T=new IntervalTree();T->root=NIL;for(int i=0;i<n;i++)IntervalT_Insert(T,A[i]);cout<<"The interval tree is:"<<endl;IntervalT_InorderWalk(T->root);cout<<"The root of the tree is:"<<T->root->inte.low<<" "<<T->root->inte.high<<endl;cout<<"/*-------------------------------------------------------------*/"<<endl;cout<<"/*--------------------Searching Interval Tree------------------*/"<<endl;interval sInt;cout<<"Please input the searching interval:";cin>>sInt.low>>sInt.high;IntervalTNode *sITNode=NIL;sITNode=IntervalT_Search(T,sInt);if(sITNode==NIL)cout<<"The searching interval doesn't exist in the tree."<<endl;else{cout<<"The overlap interval is:"<<endl;cout<<"["<<sITNode->inte.low<<" "<<sITNode->inte.high<<"]";if(sITNode->color==0)cout<<" color:RED ";elsecout<<" color:BLACK ";cout<<"Max:"<<sITNode->max<<endl;}cout<<"/*------------------Deleting INterval Tree--------------------*/"<<endl;interval dInt;cout<<"Please input the deleting interval:";cin>>dInt.low>>dInt.high;IntervalTNode *dITNode=NIL;dITNode=IntervalT_Search(T,dInt);if(dITNode==NIL)cout<<"The deleting interval doesn't exist in the tree."<<endl;else{ IntervalT_Delete(T,dITNode);cout<<"After deleting ,the interval tree is:"<<endl;IntervalT_InorderWalk(T->root);cout<<"The root of the tree is:"<<T->root->inte.low<<" "<<T->root->inte.high<<endl;}cout<<"/*------------------------------------------------------------*/"<<endl;return 0;}
运行结果:
【注:若有错误,请指正~~~】
0 0
- 算法导论 第十四章:区间树
- 算法导论 区间树
- 算法导论第十四章:数据结构的扩张
- 算法导论第十四章数据结构的扩张
- 算法导论 第十四章:数据结构的扩张
- 算法导论14.3 -区间树
- 算法导论第十四章顺序统计量树确定一个元素的秩
- 算法导论第十四章利用红黑树查找顺序统计量
- 算法导论 第14章 14.3 区间树
- 《算法导论》笔记 第14章 14.3 区间树
- 算法导论 第14章 14.3 区间树
- 算法导论 14章 数据结构的扩张(二) 区间树
- 算法导论14.3区间树 练习总结
- 算法导论34--区间树(Python)
- 算法导论学习笔记-第十四章-数据结构的扩张
- 算法导论第十四章习题14.1-4递归方式统计元素的秩
- 算法导论第十四章习题14.1-7利用顺序统计数统计数组中的逆序数
- 算法导论第十四章思考题14-1详解-求最大重叠点
- synergy使用配置<Server window7 Client Fedora21>
- [Objective-C]-02-set get语法.类方法.self关键字与点语法
- HDU 1086You can Solve a Geometry Problem too(判断线段相交模板题)
- HTTP协议详解
- Codeforces 577E Ann and Half-Palindrome 字典树
- 算法导论 第十四章:区间树
- instanceof和getClass()的区别
- 有效检查Java代码的工具:5款调试工具
- 劳累的一天啊
- jdbc与mybatis及spring
- 极光推送使用后初总结
- C语言编程基础7.8
- LeetCode---(50)Pow(x, n)
- 例题3-5 生成元(Digit Generator)