区间树

/**********************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);

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值