/**********************interval_tree.h************************/
/*头文件*/
typedef struct{
int low_endpoint;
int high_endpoint;
}inte;
typedef struct node{
inte interval;
char color;
int key;
int max;
struct node * p;
struct node *left;
struct node * right;
} Node;
void left_rotate(Node ** root,Node * x);
void right_rotate(Node ** root,Node * x);
void RB_insert(Node * *root,Node * z);
void RB_insert_fixup(Node ** root,Node * z);
void Inorder_Tree_Walk(const Node * root);
void RB_transplant(Node **root,Node *u,Node *v);
Node * RB_minimum(Node * root);
void RB_delete(Node **root,Node *z);
void RB_delete_fixup(Node **root,Node *x);
Node * Tree_Search(Node *root,int k);
void interval_search(Node * root,inte interval);
int max(Node * x);
/********************interval_T.c************************/
/*函数文件*/
#include "RBT.h"
#include <stdio.h>
extern Node sential;
void left_rotate(Node ** root,Node * x)
{ Node *y=x->right;
x->right=y->left;
if(y->left!=&sential)
y->left->p=x;
y->p=x->p;
if(x->p==&sential)
*root=y;
else if(x==x->p->left)
x->p->left=y;
else
x->p->right=y;
y->left=x;
x->p=y;
//change x's and y's max attribute
y->max=x->max;
x->max=max(x);
}
void right_rotate(Node **root,Node * x)
{ Node *y=x->left;
x->left=y->right;
if(y->right!=&sential)
y->right->p=x;
y->p=x->p;
if(x->p==&sential)
*root=y;
else if(x==x->p->right)
x->p->right=y;
else
x->p->left=y;
y->right=x;
x->p=y;
y->max=x->max;
x->max=max(x);
}
void RB_insert(Node ** root,Node * z)
{ Node *x=*root;
Node *y=&sential;
while(x!=&sential)
{ y=x;
if(z->key<x->key)
x=x->left;
else
x=x->right;
if(z->max>y->max)
y->max=z->max;
}
if (y==&sential)
*root=z;
else if(z->key<y->key)
y->left=z;
else
y->right=z;
z->p=y;
z->color='r';
z->left=&sential;
z->right=&sential;
RB_insert_fixup(root,z);
}
void RB_insert_fixup(Node ** root,Node * z)
{ while(z->p->color=='r')
{ if(z->p==z->p->p->left)
{ Node *y=z->p->p->right;
if(y->color=='r')
{ y->color='b';
z->p->color='b';
z->p->p->color='r';
z=z->p->p;
}
else
{ if (z==z->p->right)
{ z=z->p;
left_rotate(root,z);
}
right_rotate(root,z->p->p);
z->p->color='b';
z->p->right->color='r';
}
}
else
{ Node *y=z->p->p->left;
if(y->color=='r')
{ y->color='b';
z->p->color='b';
z->p->p->color='r';
z=z->p->p;
}
else
{ if(z==z->p->left)
{ z=z->p;
right_rotate(root,z);
}
left_rotate(root,z->p->p);
z->p->color='b';
z->p->left->color='r';
}
}
}
(*root)->color='b';
}
void Inorder_Tree_Walk(const Node * root)
{ if( root!=&sential)
{
Inorder_Tree_Walk(root->left);
printf("key=%5d max=%5d\n",root->key,root->max);
Inorder_Tree_Walk(root->right);
}
}
/* Don't need to chage*/
void RB_transplant(Node **root,Node *u,Node *v)
{ if(u->p==&sential)
*root=v;
else if(u->p->left==u)
u->p->left=v;
else
u->p->right=v;
v->p=u->p;
}
Node * RB_minimum(Node * root)
{ while(root->left!=&sential)
root=root->left;
return root;
}
void RB_delete(Node **root,Node *z)
{ Node *y=z;
Node *x;
char y_o_c=y->color;
if(z->left==&sential)
{ RB_transplant(root,z,z->right);
x=z->right;
}
else if(z->right==&sential)
{ RB_transplant(root,z,z->left);
x=z->left;
}
else
{ y=RB_minimum(z->right);
y_o_c=y->color;
x=y->right;
if(y->p==z)
x->p=y;
else
{ RB_transplant(root,y,x);
y->right=z->right;
y->right->p=y;
}
RB_transplant(root,z,y);
y->left=z->left;
y->left->p=y;
y->color=z->color;
y=x;
}
//change the max attribute through the simple path
// from y's original position to the root
while(y->p!=&sential)
{ y->p->max=max(y->p);
y=y->p;
}
if(y_o_c=='b')
RB_delete_fixup(root,x);
}
void RB_delete_fixup(Node **root,Node *x)
{ Node *w;
while(x->color=='b'&&x!=*root)
{ if(x==x->p->left)
{ w=x->p->right;
if(w->color=='r')
{ w->color='b';
x->p->color='r';
right_rotate(root,w);
w=x->p->right;
}
if(w->color=='b')
{ w->color='r';
x=x->p;
}
else
{ if(w->right->color=='b')
{ w->left->color='b';
w->color='r';
right_rotate(root,w);
w=x->p->right;
}
w->color=w->p->color;
w->p->color='b';
w->right->color='b';
left_rotate(root,w->p);
x=*root;
}
}
else
{ w=x->p->left;
if(w->color=='r')
{ w->color='b';
x->p->color='r';
left_rotate(root,w);
w=x->p->left;
}
if(w->color=='b')
{ w->color='r';
x=x->p;
}
else
{ if(w->left->color=='b')
{ w->right->color='b';
w->color='r';
left_rotate(root,w);
w=x->p->left;
}
w->color=w->p->color;
w->p->color='b';
w->left->color='b';
right_rotate(root,w->p);
x=*root;
}
}
}
}
Node * Tree_Search(Node *root,int k)
{ if (root==&sential||k==root->key)
return root;
if (k<root->key)
return Tree_Search(root->left,k);
else
return Tree_Search(root->right,k);
}
//function return the subtree of x's max value
int max(Node * x)
{ int max_value=x->interval.high_endpoint;
if(max_value<x->left->max)
max_value=x->left->max;
if(max_value<x->right->max)
max_value=x->right->max;
return max_value;
}
/*************************************************************
关于这个函数有两点需要说明, *
1. 如果树中确实存在区间与要查询的区间重叠,则一定可以返回一个区间 *
2. 如果进入左树中没有找到重叠的区间,那么右树一定也没有。 *
因为,左树中所有节点的high_endpoint值中, *
最大high_endpoint所在的那个区间没有与要查询的区间重合 *
说明要查询的区间在这个区间的左边或者右边, *
而查询区间的low_endpoint是小于最大的high_endpoint的, *
那么该区间必然在这个区间的左边 *
则查询区间的high_endpoint小于该区间的key值, *
根据左子树的key都小于右子树的key,必然不会重叠 *
***********************************************************/
void interval_search(Node * root,inte interval)
{ Node *x =root;
while(x!=&sential && (interval.low_endpoint>x->interval.high_endpoint ||interval.high_endpoint<x->interval.low_endpoint ))
{ if(x->left->max>interval.low_endpoint)
x=x->left;
else
x=x->right;
}
if(x!=&sential)
printf("the interval[%d,%d]\n",
x->interval.low_endpoint,x->interval.high_endpoint);
else
printf("The interval is not in the tree!\n");
}
/************************drive_interval_T.c*******************************/
/* 测试插入与删除函数对max属性的维护以及搜索函数*/
#include "RBT.h"
#include <stdio.h>
#include <stdlib.h>
Node sential={.color='b'};
int main(void)
{ Node * RBT_root=&sential;
int low,high;
printf("Please enter the interval(two interger number) to insert (q to quit)\n");
while(scanf("%d%d",&low,&high)==2)
{
Node *p_node=malloc(sizeof(Node));
p_node->key=low;
p_node->interval.low_endpoint=low;
p_node->interval.high_endpoint=high;
p_node->max=high;
RB_insert(&RBT_root,p_node);
}
printf("Sorting\n");
Inorder_Tree_Walk(RBT_root);
putchar('\n');
printf("please enter the key you want delete\n");
while(getchar()!='\n')
continue;
int k;
while(scanf("%d",&k)==1)
{ Node * res=Tree_Search(RBT_root,k);
if(res==NULL)
printf("%d is not in the BST\n",k);
RB_delete(&RBT_root,res);
}
printf("Now the RBT(after sorting)\n");
Inorder_Tree_Walk(RBT_root);
putchar('\n');
puts("please enter the interval to query");
while(getchar()!='\n')
continue;
inte temp;
while(scanf("%d%d",&temp.low_endpoint,&temp.high_endpoint)==2)
interval_search(RBT_root,temp);
}