区间树是在红黑树的基础上拓展而来的数据结构,由于基础的存储数据不同。与数据相关的操作也会不同,比如红黑树中的节点之间如何比较大小的操作。以及由比较操作的改变而带来的插入,查找,删除操作的改变。为了同时支持书中的例子和所有的练习题,数据结构中占用的空间会稍大,但是这样的数据结构无法支持练习题14.3-7,所以先把14.3-7排除在外。为此我还是使用c语言(而不使用c++ template的原因是没必要做成模板,因为真正使用的数据结构往往要远复杂与这样简单的习题,模板做的不好也无济于事)。
代码稍微多了点,主要是测试比较麻烦。代码就放在一起了。经过测试百万个随机生成的区间的插入和删除目前没有出现问题。十万节点的3种搜索操作目前都未发现问题。
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <time.h>
#include <memory.h>
#include <malloc.h>
#include <limits.h>
#define BLACK 1
#define RED 0
typedef struct Key {
int start;
int end;
}KeyP;
//ÓÃÓڱȽÏÁ½¸ö¼üÖµµÄ´óС£¬a>b 1
// a = b 0
// a<b -1
int ICmp(Key *a, Key *b)
{
if (a->start > b->start) {
return 1;
}
else if (a->start < b->start) {
return -1;
}
else {
if (a->end > b->end) {
return 1;
}
else if (a->end < b->end) {
return -1;
}
return 0;
}
return 0;
}
//·µ»ØÊÇ·ña£¬bÖ®¼ä´æÔÚ¸²¸Ç¹ØÏµ
int Interval_overlap(struct Key *a, struct Key *b) {
if (a->end < b->start || a->start > b->end)
return 0;
else return 1;
}
typedef struct node {
struct node *left;
struct node *right;
struct node *parent;
int color;
Key data;
int min_gap;
int max;
} *IBST_NODE;
void init_Interval_tree(IBST_NODE T)
{
T->left = T->right = T;
T->parent = T;
T->color = BLACK;
T->data.end = INT_MAX;
T->data.start = INT_MIN;
T->min_gap = INT_MAX;
T->max = INT_MIN;
}
IBST_NODE interval_search(IBST_NODE T, Key *i)
{
IBST_NODE x = T->left;
while (x != T&&Interval_overlap(i, &x->data) == 0) {
if (x->left != T&&x->left->max >= i->start)
{
x = x->left;
}
else
x = x->right;
}
//if(x == T)
// return 0;
return x;
}
IBST_NODE interval_search_min(IBST_NODE T, Key *i)
{
IBST_NODE x = T->left;
IBST_NODE pre = T;
while (x != T)
{
if (Interval_overlap(i, &x->data) == 1) {
pre = x;
if (x->left->max >= i->start) {
x = x->left;
}
else
x = T;
}
else {
if (x->left != T&&x->left->max >= i->start) {
x = x->left;
}
else {
x = x->right;
}
}
}
return pre;
}
static int G_SIZE;
static int num_called;
void iph_search(IBST_NODE T, Key *in, IBST_NODE x, IBST_NODE*vec)
{
//in this function ALL the node in the x's subtree is less than interval in
//the persistent condition iph_search can hold:
// all the elem y in subtree x have : y->data->start < in->start
// and x->max >= in->start;
if (x != T)
{
if (x->data.start >= in->start) {
puts("something error iph_search x->start >= in->start");
}
if (x->data.end >= in->start) {
vec[G_SIZE++] = x;
}
if (x->left->max >= in->start)
iph_search(T, in, x->left, vec);
if (x->right->max >= in->start)
iph_search(T, in, x->right, vec);
}
}
void iph_interval_search_all(IBST_NODE T, Key *in, IBST_NODE x, IBST_NODE *vec)
{
if (x != T&&x->max >= in->start)
{
num_called++;
if (x->data.start >= in->start) {
if (x->data.start <= in->end) {
//this condition means that the node x's start pos is in the interval in;
//x->data->start belongs to [in->start,in->end]
//this condition we should add x to the result vector
//and for x->left call this function again
//for x->right call this function again
vec[G_SIZE++] = x;
//if(x->left->max >= in->start)
iph_interval_search_all(T, in, x->left, vec);
//if(x->right->max >= in->start