要求:对实验二的红黑树进行扩展,构造1000个节点的区间树,在区间树上查找具有最小低端点的重叠区间
思想:
1.对红黑树节点的扩展:每个节点结构如下:
typedef structnode{
timeval itimeval; //时间区间
int key; //关键字:区间中的低端节点值
int max;
//Max(pnode->left->max,pnode->right->max,pnode->itimeval.high);
struct node * left;
struct node * right;
struct node * parent;
enum rb_color color;
}TimeValNode,*TimeValTree;
2.对红黑树旋转算法的修改
旋转节点后修改相应节点的max值。
3.对红黑树插入算法的修改
插入的节点肯定在最底端(不考虑NIL节点),这个会破坏max的值在红黑树中定义的性质,因此需要自底向上的调整从树根到该插入节点的路径上所有节点的max值。
head.h:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
enum rb_color {RED,BLACK};
typedef struct timeval{
int low;
int high;
}timeval;
typedef struct node{
timeval itimeval;
int key;
int max;
struct node * left;
struct node * right;
struct node * parent;
enum rb_color color;
}TimeValNode,*TimeValTree;
TimeValTree NIL;
void Init();
TimeValTree Creat_Node(TimeValTree*,timeval);
void Left_Rotate(TimeValTree*,TimeValTree);
void Right_Rotate(TimeValTree*,TimeValTree);
void RB_Insert(TimeValTree*,TimeValTree);
void RB_Insert_Fixup(TimeValTree*,TimeValTree);
void Inorder(TimeValTree );
void Preorder(TimeValTree );
int height(TimeValTree );
TimeValTree InterVal_Search(TimeValTree,timeval);
lab.c文件:
#include "head.h"
void Init(){
NIL = (TimeValTree)malloc(sizeof(TimeValNode));
NIL->key = 0;
NIL->itimeval.low = 0;
NIL->itimeval.high = 0;
NIL->max = 0;
NIL->left= NULL;
NIL->parent = NULL;
NIL->right = NULL;
NIL->color = BLACK;
}
int GetMax(int a,int b,int c){
return (a=a>b?a:b)>c?a:c;
}
TimeValTree Creat_Node(TimeValTree *pnode,timeval itimeval){
if(((*pnode) = (TimeValTree)malloc(sizeof(TimeValNode)))!=NULL){
(*pnode)->itimeval.high = itimeval.high;
(*pnode)->itimeval.low = itimeval.low;
(*pnode)->key = itimeval.low;
(*pnode)->max = itimeval.high;
(*pnode)->left = NIL;
(*pnode)->right = NIL;
(*pnode)->parent = NIL;
(*pnode)->color = RED;
return *pnode;
}
else return NULL;
}
void Left_Rotate(TimeValTree * T,TimeValTree pnode){
TimeValTree temp = pnode->right;
pnode->right = temp->left;
if(temp->left!=NIL)
temp->left->parent = pnode;
temp->parent = pnode->parent;
if(pnode->parent==NIL)
*T = temp;
else if(pnode->parent->left==pnode)
pnode->parent->left = temp;
else
pnode->parent->right = temp;
temp->left = pnode;
pnode->parent = temp;
temp->max =pnode->max;
pnode->max=GetMax(pnode->left->max,temp->left->max,pnode->itimeval.high);
}
void Right_Rotate(TimeValTree * T,TimeValTree pnode){
TimeValTree temp = pnode->left;
pnode->left = temp->right;
if(temp->right!=NIL)
temp->right->parent = pnode;
temp->parent = pnode->parent;
if(pnode->parent==NIL)
*T = temp;
else if(pnode->parent->left==pnode)
pnode->parent->left = temp;
else
pnode->parent->right = temp;
temp->right = pnode;
pnode->parent = temp;
temp->max =pnode->max;
pnode->max=GetMax(pnode->right->max,temp->right->max,pnode->itimeval.high);
}
void RB_Insert(TimeValTree *T,TimeValTree pnode){
TimeValTree ptemp = *T,qtemp = NIL;
//if(pnode==NULL) {printf("pnode is null\n");return;}
while(ptemp!=NIL){
qtemp = ptemp;
if(pnode->key < ptemp->key)
ptemp = ptemp->left;
else
ptemp = ptemp->right;
}
pnode->parent = qtemp;
if(qtemp == NIL)
*T = pnode;
else if (pnode->key > qtemp->key)
qtemp->right = pnode;
else
qtemp->left = pnode;
pnode->left = NIL;
pnode->right = NIL;
pnode->color = RED;
RB_Insert_Fixup(T,pnode);
while(pnode!=NIL){
pnode->max = GetMax(pnode->left->max,pnode->right->max,pnode->itimeval.high);
pnode = pnode->parent;
}
}
void RB_Insert_Fixup(TimeValTree* T,TimeValTree pnode){
TimeValTree ptemp = NULL;
while(pnode->parent->color==RED){
if(pnode->parent==pnode->parent->parent->left){
ptemp = pnode->parent->parent->right;
if(ptemp->color==RED){
pnode->parent->color = BLACK;
pnode->parent->parent->color = RED;
ptemp->color = BLACK;
pnode = pnode->parent ->parent ;
}
else{
if(pnode->parent->right==pnode){ //case2:
pnode = pnode->parent ;
Left_Rotate(T,pnode);
}
pnode->parent->color = BLACK;
pnode->parent->parent->color = RED;
Right_Rotate(T,pnode->parent->parent);
}
}//if
else{
ptemp = pnode->parent->parent->left;
if(ptemp->color==RED){
pnode->parent->color = BLACK;
pnode->parent->parent->color = RED;
ptemp->color = BLACK;
pnode = pnode->parent ->parent ;
}
else{
if(pnode->parent->left==pnode){ //case2:
pnode = pnode->parent ;
Right_Rotate(T,pnode);
}
pnode->parent->color = BLACK;
pnode->parent->parent->color = RED;
Left_Rotate(T,pnode->parent->parent);
}
}//else
}//while
(*T)->color = BLACK;
}
void Inorder(TimeValTree T){
if(T!=NIL){
Inorder(T->left);
printf("timeval:%d---%d\tmax:%d\tcolor:%s\n",T->itimeval.low,T->itimeval.high,T->max,T->color?"BLACK":"RED");
Inorder(T->right);
}
}
void Preorder(TimeValTree T){
if(T!=NIL){
printf("timeval:%d---%d\tmax:%d\tcolor:%s\n",T->itimeval.low,T->itimeval.high,T->max,T->color?"BLACK":"RED");
Preorder(T->left);
Preorder(T->right);
}
}
int height(TimeValTree T){
int left,right;
if(T==NIL) return 0;
left = height(T->left);
right = height(T->right);
return left>right?left+1:right+1;
}
int IsOverlap(timeval itimeval_1,timeval itimeval_2 ){
if(itimeval_1.low<=itimeval_2.high && itimeval_1.high>=itimeval_2.low)
return 1;
return 0;
}
/*
TimeValTree InterVal_Search(TimeValTree T,timeval itimeval){
TimeValTree pnode;
if(T->max<itimeval.low || T==NIL ) return NIL;
if(T->left!=NIL && T->left->max>=itimeval.low){
pnode = InterVal_Search(T->left,itimeval);
if(pnode!=NIL)
return pnode;
else if(IsOverlap(T->itimeval,itimeval))
return T;
else
return NIL;
}
else if(IsOverlap(T->itimeval,itimeval))
return T;
else
return InterVal_Search(T->right,itimeval);
}
*/
TimeValTree InterVal_Search(TimeValTree T,timeval itimeval){
TimeValTree pnode;
if(T->max<itimeval.low || T==NIL ) return NIL;
if(T->left!=NIL && T->left->max>=itimeval.low){
return InterVal_Search(T->left,itimeval);
}
else if(IsOverlap(T->itimeval,itimeval))
return T;
else
return InterVal_Search(T->right,itimeval);
}
main.c文件:
#include"head.h"
int main(){
TimeValTree T ,pnode;
int i,k1,k2;
timeval itimeval;
Init();
T = NIL;
pnode = NULL;
/*/...........................
itimeval.low = 16;
itimeval.high = 21;
if(Creat_Node(&pnode,itimeval)==NULL){
printf("fail to creat node...\n");
exit(1);
}
RB_Insert(&T,pnode);
itimeval.low = 8;
itimeval.high = 9;
if(Creat_Node(&pnode,itimeval)==NULL){
printf("fail to creat node...\n");
exit(1);
}
RB_Insert(&T,pnode);
itimeval.low = 25;
itimeval.high = 30;
if(Creat_Node(&pnode,itimeval)==NULL){
printf("fail to creat node...\n");
exit(1);
}
RB_Insert(&T,pnode);
itimeval.low = 5;
itimeval.high = 8;
if(Creat_Node(&pnode,itimeval)==NULL){
printf("fail to creat node...\n");
exit(1);
}
RB_Insert(&T,pnode);
itimeval.low = 15;
itimeval.high = 23;
if(Creat_Node(&pnode,itimeval)==NULL){
printf("fail to creat node...\n");
exit(1);
}
RB_Insert(&T,pnode);
itimeval.low = 17;
itimeval.high = 19;
if(Creat_Node(&pnode,itimeval)==NULL){
printf("fail to creat node...\n");
exit(1);
}
RB_Insert(&T,pnode);
itimeval.low = 26;
itimeval.high = 26;
if(Creat_Node(&pnode,itimeval)==NULL){
printf("fail to creat node...\n");
exit(1);
}
RB_Insert(&T,pnode);
itimeval.low = 0;
itimeval.high = 3;
if(Creat_Node(&pnode,itimeval)==NULL){
printf("fail to creat node...\n");
exit(1);
}
RB_Insert(&T,pnode);
itimeval.low = 6;
itimeval.high = 10;
if(Creat_Node(&pnode,itimeval)==NULL){
printf("fail to creat node...\n");
exit(1);
}
RB_Insert(&T,pnode);
itimeval.low = 19;
itimeval.high = 20;
if(Creat_Node(&pnode,itimeval)==NULL){
printf("fail to creat node...\n");
exit(1);
}
RB_Insert(&T,pnode);
//.......................................*/
srand((unsigned)time(NULL));
for(i = 0;i<1000;i++){
itimeval.low=rand() % 2000;
itimeval.high = itimeval.low + 30;
if(Creat_Node(&pnode,itimeval)==NULL){
printf("fail to creat node...\n");
exit(1);
}
RB_Insert(&T,pnode);
}
//printf("InOrder:\n");
//Inorder(T);
//printf("\nPreOrder:\n");
//Preorder(T);
//printf("\nheight:%d\n",height(T));
itimeval.low = 32;
itimeval.high = 35;
pnode = InterVal_Search(T,itimeval);
if(pnode!=NIL)
printf("timeval:%d---%d\tmax:%d\tcolor:%s\n",pnode->itimeval.low,pnode->itimeval.high,pnode->max,pnode->color?"BLACK":"RED");
else
printf("no such timeval\n");
}