题目:在红黑树的基础上实现区间树的创建,左旋,右旋,插入和查找
算法思想:
区间树介绍:
区间树是在红黑树基础上进行扩展得到的支持以区间为元素的动态集合的操作,其中每个节点的关键值是区间的左端点。区间[low,high]表示成一个对象i,low表示区间的低点,high表示区间的高点。通过建立这种特定的结构,可使区间的元素的查找和插入都可以在O(lgn)的时间内完成。
相比于红黑树的数据结构,区间树还增加了一个max[x],即以x为根的子树中所有区间的断点的最大值:
max[x]=max(high[int[x]], max[left[x]],max[right[x]]
以红黑树为基础,对x∈T,x包含区间int[x]的信息(低点和高点),key=low[int[x]]。
设计区间树的数据结构如下:
typedef enum Color{red,black}Color;
typedef structinterval{//区间
int low;
int high;
}interval;
struct rbnode{
int key;//区间的低端点
struct rbnode *left;
struct rbnode *right;
struct rbnode *p;
int max;//以当前结点为子树的所有区间的端点的最大值
interval inte;
Color color;
}RBnode;
typedef structrbnode *RBTree;
代码如下:
#include <iostream> #include <stdlib.h> #include <string.h> #include <algorithm> #include <stack> #include<time.h> #include <stdio.h> //#deifine NUM 10 int NUM = 1000; using namespace std; typedef enum Color{red,black} Color; typedef struct interval{//区间 int low; int high; }interval; struct rbnode{ int key;//区间的低端点 struct rbnode *left; struct rbnode *right; struct rbnode *p; int max;//以当前结点为子树的所有区间的端点的最大值 interval inte; Color color; }RBnode; typedef struct rbnode *RBTree; RBTree nil,root; int Overlap(interval a,interval b);//两个区间是否重叠 void InitLeafNode();//初始化叶子结点 int GetMax(RBTree T); int Max(int a,int b,int c); RBTree CreateNode(int key,Color color);//创建一个新的树结点 void Interval_insert(RBTree &T,RBTree z);//插入 void In_insert_fixup(RBTree &T,RBTree z);//区间树插入的调整 RBTree Interval_search(RBTree T,interval i);//查找区间 void Left_rotate(RBTree &T,RBTree z);//区间树的左旋 void Right_rotate(RBTree &T,RBTree y);//区间树的右旋 RBTree TreeMinimum(RBTree x);//找到树中最小的key RBTree TreeSuccessor(RBTree x);//找到中序遍历下的后继并返回 void PrintRBTree(RBTree T);//中序遍历输出结点 int Overlap(interval a,interval b) { if(a.low>b.high||a.high<b.low)//如果两个区间没有交集返回1 return 1; else return 0; } void InitLeafNode()//初始化叶子结点 { nil = (RBTree)malloc(sizeof(RBnode)); root = (RBTree)malloc(sizeof(RBnode)); nil->color=black; nil->left=NULL; nil->right=NULL; nil->key=-1; nil->max = -1; nil->inte.low = nil->inte.high = -1; root = nil; } RBTree CreateNode(int key,int high,Color color) { RBTree x; x = (RBTree)malloc(sizeof(RBnode)); x->key = key; x->color = color; x->left = x->right = nil; x->p = NULL; x->inte.high = high; x->inte.low = key; x->max = high; return x; } int GetMax(RBTree T) { // int max; if(T->left == nil&&T->right == nil) { return T->inte.high; // max = x->inte.high>=GetMax(x->left)?x->inte.high:GetMax(x->left); // T->max = max>=GetMax(x->right)?max:GetMax(x->right); } else return Max(T->inte.high,GetMax(T->left),GetMax(T->right)); } int Max(int a,int b,int c) { int d; d = a>=b?a:b; return d>=c?d:c; } void Interval_insert(RBTree &T,RBTree z) { RBTree y = nil; RBTree x = root; while(x != nil) { // x->max = GetMax(x); if(x->max < z->max) x->max = z->max; 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; In_insert_fixup(T,z); // z->max = GetMax(z); } void In_insert_fixup(RBTree &T,RBTree z) { RBTree uncle; while(z->p->color == red) { if(z->p == z->p->p->left) { uncle = z->p->p->right; if(uncle->color == red)//case 1 { z->p->color = black; uncle->color = black; z->p->p->color = red; z = z->p->p; } else { if(z->p->right == z)//case 2 { z = z->p; Left_rotate(T,z); } z->p->color = black;//case 3 z->p->p->color = red; Right_rotate(T,z->p->p); } } else { uncle = z->p->p->left; if(uncle->color == red) { z->p->color = black; uncle->color = black; z->p->p->color = red; z = z->p->p; } else { if(z->p->left == z) { z = z->p; Right_rotate(T,z); } z->p->color = black; z->p->p->color = red; Left_rotate(T,z->p->p); } } } root->color = black; } void Left_rotate(RBTree &T,RBTree z) { RBTree y; y = z->right; z->right = y->left; if(y->left != nil) { y->left->p = z; } y->p = z->p; if(z->p != nil) { if(z == z->p->left) z->p->left = y; else z->p->right = y; } else root = y; y->left = z; z->p = y; //附加信息的维护 y->max = z->max; z->max = Max(z->inte.high,z->left->max,z->right->max); } void Right_rotate(RBTree &T,RBTree y) { RBTree x; x = y->left; y->left= x->right; if( x->right!=nil) { x->right->p = y; } x->p = y->p; if( y->p != nil) { if(y == y->p->right) y->p->right = x; else y->p->left = x; } else root = x; x->right = y; y->p = x; //附加信息的维护 x->max = y->max; y->max = Max(y->inte.high,y->left->max,y->right->max); } RBTree TreeMinimum(RBTree x)//查找以x为根的最小区间结点 { while(x->left != nil) { x = x->left; } return x; } RBTree TreeSuccessor(RBTree x)//查找x的后继结点 { RBTree y; if (x->right != nil) { return TreeMinimum(x->right); } y = x->p; while (y != nil && x == y->right) { x = y; y = y->p; } return y; } int node = 0; void PrintRBTree(RBTree T)//区间树的输出 { if(T != nil) { for(int i = 0; i <= node;i++) { printf(" "); } printf("([%d,%d],%d,",T->key,T->inte.high,T->max); if(T->color == black) { printf("B,\n"); } else printf("R,\n"); node++; PrintRBTree(T->left); PrintRBTree(T->right); node--; for(int j = 0; j <= node;j++) { printf(" "); } printf("),\n"); } else { for(int i = 0; i <= node;i++) { printf(" "); } printf("Nil,\n"); } } RBTree Interval_search(RBTree T,interval i)//查找区间 { RBTree x; x = T; while(x != nil && Overlap(i,x->inte)) { if(x->left != nil&&x->left->max>=i.low) x = x->left; else x = x->right; } return x; } int main() { RBTree node[NUM]; int num = 0;//要插入的结点数 InitLeafNode(); printf("请输入你要建立红黑树的结点数目: "); scanf("%d",&num); int key=0; int high = 0; printf("请依次输入%d个结点的值:",num); for(int i = 0; i < num; i++) { scanf("%d,%d",&key,&high); node[i]=CreateNode(key,high,red); Interval_insert(root,node[i]); } /*输出插入结点后树的模型*/ printf("生成的区间树如下:\n"); PrintRBTree(root); //查找 printf("请输入区间:(形如 a,b)"); interval i; int l,h; while((scanf("%d,%d",&l,&h))!=EOF) { i.low = l; i.high = h; RBTree x = Interval_search(root,i); if(x!= nil) { printf("find success and interval is [%d,%d]\n",x->key,x->inte.high); } else printf("This interval does not exist.\n"); printf("请输入区间:"); } }