线段树(segment tree) code
来源:互联网 发布:济南java培训 编辑:程序博客网 时间:2024/05/22 07:01
线段树(segment tree)
线段树是一棵二叉树,记为T(a, b),参数a,b表示区间[a,b],其中b-a称为区间的长度,记为L。
线段树T(a,b)递归定义类似为:
若L>1 : [a, (a+b) div 2]为 T的左儿子; [(a+b) div 2,b]为T 的右儿子。 若L=1 : T为叶子节点。
上面的线段树只是一种可能的形式,具体按自己的需求定义,只要保证父节点“覆盖”所有的子节点
例:
桌子上零散地放着若干个盒子,桌子的后方是一堵墙。如图所示。现在从桌子的前方射来一束平行光, 把盒子的影子投射到了墙上。问影子的总宽度是多少?
这道题目是一个经典的模型。在这里,我们略去某些处理的步骤,直接分析重点问题,可以把题目抽象地描述如下:x轴上有若干条线段,求线段覆盖的总长度,即S1+S2的长度。
code:
#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct Node{int lvalue, rvalue;int data;struct Node *lchild;struct Node *rchild;} Node;Node *Build(int l, int r){Node *root;if (l >= r)return NULL;root = (Node *)calloc(1, sizeof(Node));root->lvalue = l;root->rvalue = r;root->data = 0;root->lchild = NULL;root->rchild = NULL;if (l + 1 < r) {int mid = (l + r) >> 1;root->lchild = Build(l , mid) ;root->rchild = Build(mid , r) ; } return root; }void Insert(Node *root, int c, int d){if (!root)return;if(c <= root->lvalue && d >= root->rvalue) root->data++;else {int mid = (root->lvalue + root->rvalue) >> 1;if (d <= mid) Insert(root->lchild, c, d);else if(c >= mid) Insert(root->rchild, c, d);else {Insert(root->lchild, c, mid);Insert(root->rchild, mid, d);}}} void Delete(Node *root, int c, int d){if (!root)return;if (c <= root->lvalue && d >= root->rvalue) root->data--;else {int mid = (root->lvalue + root->rvalue) >> 1;if (d <= mid) Delete(root->lchild, c, d);else if(c >= mid) Delete(root->rchild, c, d);else {Delete(root->lchild, c, mid);Delete(root->rchild, mid, d);}}} void Find(Node *root,int a,int b, int *count) { int mid;if (!root)return;if(root->data > 0) {*count += (root->rvalue - root->lvalue); return; }mid = (root->lvalue + root->rvalue) >> 1; if(b <= mid) Find(root->lchild, a, b, count); else if(a >= mid) Find(root->rchild,a, b, count);else { Find(root->lchild, a, mid, count); Find(root->rchild, mid, b, count); } }int value[][2] = {{1, 7},{8, 17},{15, 23},{34, 40},{38, 42},{36, 41}};int main(){int count = 0;int i;Node *root = Build(9, 101);for (i = 0; i < sizeof(value) / sizeof(value[0]); i++)Insert(root, value[i][0], value[i][1]);Find(root, 4, 50, &count);printf("count: %d\n", count);Delete(root, 36, 41);count = 0;Find(root, 4, 50, &count);printf("count: %d\n", count);Delete(root, 38, 42);count = 0;Find(root, 4, 50, &count);printf("count: %d\n", count);return 0;}
0 0
- 线段树(segment tree) code
- 线段树(segment tree)
- 线段树(segment tree)
- 线段树(segment tree)
- 线段树(segment tree)
- 线段树(segment tree)
- 线段树(segment tree)
- segment tree(线段树)
- 线段树(segment tree)
- 浅谈线段树 Segment Tree
- Segment Tree-线段树学习
- XTU1238:Segment Tree(线段树)
- XTU1238:Segment Tree(线段树)
- 线段树(Segment Tree)
- 浅谈线段树(Segment Tree)
- 线段树(segment tree)
- Segment Tree 线段树总结
- segment tree(线段树)
- 【设计模式基础】创建型模式 - 4 - 工厂方法(Factory Method)
- Populating Next Right Pointers in Each Node
- char*数组(c类型字符串)和Vc++中的CString的转换,char*数组等问题
- Java学习路线图【超级详细】
- 1314跨年我在干嘛
- 线段树(segment tree) code
- Ubuntu文件编码转码(gbk<-->utf8)和中文编码--Ubuntu小笔记
- java学习书籍
- 使用Unity的50个建议:Part1(译文)
- 使用Unity的50个建议:Part2(译文)
- sqlserver excel 导入数据(图解)
- UVALive - 3621 Power Calculus
- 本地搭建wordpress
- Git 7注意