区间树查找
来源:互联网 发布:ios 无网络界面 编辑:程序博客网 时间:2024/05/14 16:19
一、算法的分析
1、基本概念:
区间:一个事件占用的时间
闭区间:实数的有序对[t1,t2],使t1≤t2
区间的对象表示:[t1,t2]可以用对象i表示,有两个属性:
low[i]=t1//起点或低点
high[i]=t2//终点或高点
区间的重叠:i∩i’≠Ø ⇔(low[i]≤high[i’]) and (low[i’]≤high[i])
2、数据结构:本质上是将红黑树扩充,方法如下:
Step 1:基本结构。以红黑树为基础,对∀x∈T,x包含区间int[x]的信息(低点和高点),key=low[int[x]]。
Step 2:附加信息。max[x]=max(high[int[x]], max[left[x]], max[right[x]])
Step 3:维护附加信息(有效性)。由定理14.1及max的定义⇒有效
Step 4:开发新操作。查找与给定区间重叠的区间keymax节点x
3、查找算法IntervalSearch(T, i)基本思想:
step 1:x ←root[T];//从根开始查找
step 2:若x≠nil[T]且i与int[x]不重叠
if x的左子树非空且左子树中最大高点≥low[i] then
x ←left[x];//到x的左子树中继续查找
else //左子树必查不到,到右子树查
x ←right[x];
step 3:返回x //x=nil or i和x重叠
由于区间树是红黑树的简单扩重,因此区间树相关操作的实现如左旋、右旋、插入,插入调整等与红黑树基本相同,具体而言,仅仅在左旋和右旋的操作中维护max域的取值正确即可,其他与红黑树操作完全相同。
二、上机代码
1、基本概念:
区间:一个事件占用的时间
闭区间:实数的有序对[t1,t2],使t1≤t2
区间的对象表示:[t1,t2]可以用对象i表示,有两个属性:
low[i]=t1//起点或低点
high[i]=t2//终点或高点
区间的重叠:i∩i’≠Ø ⇔(low[i]≤high[i’]) and (low[i’]≤high[i])
2、数据结构:本质上是将红黑树扩充,方法如下:
Step 1:基本结构。以红黑树为基础,对∀x∈T,x包含区间int[x]的信息(低点和高点),key=low[int[x]]。
Step 2:附加信息。max[x]=max(high[int[x]], max[left[x]], max[right[x]])
Step 3:维护附加信息(有效性)。由定理14.1及max的定义⇒有效
Step 4:开发新操作。查找与给定区间重叠的区间keymax节点x
3、查找算法IntervalSearch(T, i)基本思想:
step 1:x ←root[T];//从根开始查找
step 2:若x≠nil[T]且i与int[x]不重叠
if x的左子树非空且左子树中最大高点≥low[i] then
x ←left[x];//到x的左子树中继续查找
else //左子树必查不到,到右子树查
x ←right[x];
step 3:返回x //x=nil or i和x重叠
由于区间树是红黑树的简单扩重,因此区间树相关操作的实现如左旋、右旋、插入,插入调整等与红黑树基本相同,具体而言,仅仅在左旋和右旋的操作中维护max域的取值正确即可,其他与红黑树操作完全相同。
二、上机代码
#include <stdio.h>#include <stdlib.h>#include <time.h>#include <string.h>enum NODECOLOR{ BLACK =0, RED =1};typedef struct INTERVALTree{ struct INTERVALTree *parent; struct INTERVALTree *left,*right; int key; int max; int low; int high; NODECOLOR color;}INTERVALTree, *PINTERVALTree;void LEFT_ROTATE(PINTERVALTree x,PINTERVALTree root);void RIGHT_ROTATE(PINTERVALTree x,PINTERVALTree root);PINTERVALTree INTERVAL_INSERT(int key,int low,int high,PINTERVALTree root);PINTERVALTree INTERVAL_INSERT_FIXUP(PINTERVALTree root,PINTERVALTree z);PINTERVALTree INTERVAL_SEARCH(PINTERVALTree root,int low,int high);void preorder_visit(PINTERVALTree t);void print_node(PINTERVALTree node);void LEFT_ROTATE(PINTERVALTree x,PINTERVALTree root){ PINTERVALTree y; int i,j; /*用于存放原来x和y的max值*/ y=x->right; i=x->max; j=y->max; x->right=y->left; if(y->left!=NULL) y->left->parent=x; y->parent=x->parent; if(x->parent==NULL) root=y; else if(x==x->parent->left) x->parent->left=y; else x->parent->right=y; y->left=x; x->parent=y; if(x->high>j) x->max=x->high; else x->max=j; if(y->high>i) y->max=y->high; else y->max=i;}void RIGHT_ROTATE(PINTERVALTree x,PINTERVALTree root){ PINTERVALTree y; int i=0,j=0; /*用于存放原来x和y的max值*/ i=x->max; j=y->max; y=x->left; x->left=y->right; if(y->right!=NULL) y->right->parent=x; y->parent=x->parent; if(x->parent==NULL) root=y; else if(x==x->parent->left) x->parent->left=y; else x->parent->right=y; x->parent=y; y->right=x; if(x->high>j) x->max=x->high; else x->max=j; if(y->high>i) y->max=y->high; else y->max=i;}PINTERVALTree INTERVAL_INSERT(int key,int low,int high,PINTERVALTree root){ PINTERVALTree x,y; PINTERVALTree z; z=(PINTERVALTree)malloc(sizeof(INTERVALTree)); z->key=key; z->max=high; z->low=low; z->high=high; y=NULL; x=root; while(x!=NULL) { y=x; if(z->key<x->key) x=x->left; else x=x->right; } z->parent=y; if(y==NULL) root=z; else if(z->key<y->key) y->left=z; else y->right=z; z->left=z->right=NULL; z->color=RED; return INTERVAL_INSERT_FIXUP(root,z);}PINTERVALTree INTERVAL_INSERT_FIXUP(PINTERVALTree root,PINTERVALTree z){ PINTERVALTree y,a; a=z; while(z!=root&&z->parent->color==RED) { if(z->parent==z->parent->parent->left) { y=z->parent->parent->right; if(y->color==RED) { y->color=BLACK; z->parent->color=BLACK; z->parent->parent->color=RED; z=z->parent->parent; } else { if(z==z->parent->right) { z=z->parent; LEFT_ROTATE(z,root); } z->parent->color=BLACK; z->parent->parent->color=RED; RIGHT_ROTATE(z->parent->parent,root); } } else { 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(z,root); } z->parent->color=BLACK; z->parent->parent->color=RED; LEFT_ROTATE(z->parent->parent,root); } } } while(a->parent!=NULL&&a->parent->max<a->max) { a->parent->max=a->max; a=a->parent; } root->color=BLACK; return root;}PINTERVALTree INTERVAL_SEARCH(PINTERVALTree root,int low,int high){ PINTERVALTree x; x=root; while(x!=NULL&&(x->high < low || high < x->low)) { if((x->left!=NULL)&&(x->left->max>=low)) x=x->left; else x=x->right; } return x;}void preorder_visit(PINTERVALTree t){ if(t!=NULL) { print_node(t); if(t->left!=NULL) preorder_visit(t->left); if(t->right!=NULL) preorder_visit(t->right); }}void print_node(PINTERVALTree node){ char *color[]={"BLACK","RED"}; printf("%d %d %d %d %s ",node->key,node->max,node->low,node->high,color[node->color]);}int main(){ PINTERVALTree root=NULL; PINTERVALTree node; int low,high; char c1,c2,c3,c4; char s1[7]=""; char s2[5]="exit"; char s3[5]="find"; char s4[7]="insert"; char s5[7]=""; while(strcmp(s1,s2)!=0) { printf("请输入输入相关实验数据,(exit/insert [xx,xx]):"); scanf("%s",s1); if(strcmp(s1,s4)==0) { scanf("%c",&c1); scanf("%c",&c2); scanf("%d",&low); scanf("%c",&c3); scanf("%d",&high); scanf("%c",&c4); root=INTERVAL_INSERT(low,low,high,root); } else if(strcmp(s1,s2)==0) break; } preorder_visit(root); printf("\n"); printf("\n"); while(strcmp(s5,s2)!=0) { printf("请输入查找区间(find [xx,xx]):"); scanf("%s",s5); if(strcmp(s5,s3)==0) { scanf("%c",&c1); scanf("%c",&c2); scanf("%d",&low); scanf("%c",&c3); scanf("%d",&high); scanf("%c",&c4); node=INTERVAL_SEARCH(root,low,high); if(node!=NULL) printf("\n区间[%d,%d]重叠的区间是:[%d,%d]\n",low,high,node->low,node->high); else printf("\n没有重叠的区间\n"); } else if(strcmp(s5,s2)==0) break; } return 0;}
0 0
- 区间树查找算法
- 区间树查找
- 二叉查找树搜索区间
- POJ 2528 线段树区间查找区间询问
- 线段树更新区间查找点
- 题目:二叉查找树中搜索区间
- 二叉查找树中搜索区间
- 1564: [NOI2009]二叉查找树 区间DP
- 【BZOJ1564】[NOI2009]二叉查找树【区间DP】
- 二叉查找树中搜索区间
- 二叉查找树中搜索区间
- Lintcode 二叉查找树中搜索区间
- 二叉查找树中搜索区间
- lintcode-二叉树中查找区间
- 二叉查找树中搜索区间
- 查找断号区间
- xmu 1170区间查找
- hdu4391(线段树查找区间内出现的个数)
- Codeforces 149D - Coloring Brackets(区间DP)
- cookie的应用
- 文件操作:fseek函数和ftell函数
- git分支管理
- Android中Bitmap和Drawable
- 区间树查找
- 最小生成树的Kruskal算法
- vi常用命令操作
- 屋漏偏逢连夜雨,智利超模主动承认与C罗滚过床单
- 分治法求平面上的最小点对
- 每日一题F
- 关于 AppDelegate 、UIApplication 简单的用法
- 黑马程序员——Java基础---集合(Collection和List)
- leetcode--Anagrams