線段樹啊

from a PPT

【代碼】

#include<stdio.h>
#define MAXN 10
struct node
{
	int left,right,mid;
	int cover;
};

node seg_tree[3*MAXN];
/*
由樹的性質可知,建樹所需的空間大概是所需處理最長線段
長度的2倍多,所以需要開3倍大小的數組.
不懂的說...
*/

void make(int l,int r,int num)
{
	//l,r分別爲當前節點的左右端點,num爲節點在數組中的編號.
	seg_tree[num].left=l;
	seg_tree[num].right=r;
	seg_tree[num].mid=(l+r)/2;
	if((l+1)!=r)
	{
		//若不爲葉子節點,則遞歸的建立左右樹
		make(l,seg_tree[num].mid,2*num);
		make(seg_tree[num].mid,r,2*num+1);
	}
}

void insert(int l,int r,int num)
{
	//l,r分別爲插入當前節點線段的左右端點,num爲節點在數組中的編號.
	if(seg_tree[num].left==l&&seg_tree[num].right==r)
	{
		//若插入的線段完全覆蓋當前節點所表示的線段
		seg_tree[num].cover=1;
		return ;
	}
	if(r<=seg_tree[num].mid)
		//當前節點的左節點所代表的線段包含插入的線段
		insert(l,r,2*num);
	else if(l>=seg_tree[num].mid)
		//當前節點的右節點所代表的線段包含插入的線段
		insert(l,r,2*num+1);
	else
	{
		//插入的線段跨越了當前節點所代表線段的中點
		insert(l,seg_tree[num].mid,2*num);
		insert(seg_tree[num].mid,r,2*num+1);
	}
}

int del(int l,int r,int num)//原爲bool
{
	if(seg_tree[num].left+1==seg_tree[num].right)
	{
		//刪除到葉節點的情況
		int f=seg_tree[num].cover;//cover??
		seg_tree[num].cover=0;
		return f;
	}
	if(seg_tree[num].cover==1)
	{
		//當前節點不爲葉節點且被覆蓋
		seg_tree[num].cover=0;
		seg_tree[2*num].cover=1;
		seg_tree[2*num+1].cover=1;
	}
	if(r<=seg_tree[num].mid)
		return del(l,r,2*num);
	else if(l>=seg_tree[num].mid)
		return del(l,r,2*num+1);
	else
		return del(l,seg_tree[num].mid,2*num)&&del(seg_tree[num].mid,r,2*num+1);
}

int cal(int num)
{
	if(seg_tree[num].cover)
		return seg_tree[num].right-seg_tree[num].left+1;
	if(seg_tree[num].left+1==seg_tree[num].right)
		//當遍歷到葉節點時返回
		return 0;
	return cal(2*num)+cal(2*num+1);
}

int main()
{
	int l=1,r=10,num=1;
	make(l,r,num);
	insert(2,9,1);
	printf("%d\n",cal(5));
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章