算法导论14.3 -区间树

这篇博客介绍了如何在C语言中实现算法导论中的区间树。区间树是一种基于红黑树扩展的数据结构,用于处理区间查询和操作。虽然为适应各种练习题,数据结构设计得较为复杂,但不支持练习题14.3-7。作者选择使用C语言而非C++模板来编写代码,因为实际应用中的数据结构通常更复杂,而且模板不一定适用。文章包含了大量测试代码,确保百万个随机区间插入和删除以及十万节点的搜索操作的正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

区间树是在红黑树的基础上拓展而来的数据结构,由于基础的存储数据不同。与数据相关的操作也会不同,比如红黑树中的节点之间如何比较大小的操作。以及由比较操作的改变而带来的插入,查找,删除操作的改变。为了同时支持书中的例子和所有的练习题,数据结构中占用的空间会稍大,但是这样的数据结构无法支持练习题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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值