热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Implementation:SegmentTree线段树

早就听人提起过线段树,今天有题搞不出来,讨论上说要用一下线段树,看了下,本质上是空间划分索引,只不过是一维上面的,如果在二维则是四叉树,三维则是八叉树,如果可以动态调整那么跟R-T

早就听人提起过线段树,今天有题搞不出来,讨论上说要用一下线段树,看了下,本质上是空间划分索引,只不过是一维上面的,如果在二维则是四叉树,三维则是八叉树,如果可以动态调整那么跟R-Tree就很相似了,他们都可以对范围查询做出响应。参照书上写了一个,虽然不多,但是渣渣也写的很是费力



#include
#include

#include

using namespace std;
class SegmentTree {
private:
int *mem;
int capacity;
int storage_size;
private:
void init_level_update() {
int k = capacity - 1;
while (--k >= 0) {
int L = (k<<1) + 1;
int R = L + 1;
mem[k]
= min(mem[L], mem[R]);
}
}
int query(int a, int b, int idx, int L, int R) {
if (b <= L || a >= R) return INT_MAX;
if (a <= L && R <= b) return mem[idx];
int ml = query(a, b, (idx<<1) + 1, L, (L+R)/2);
int mr = query(a, b, (idx<<1) + 2, (L+R)/2, R);
return min(ml, mr);
}

void init_mem(int _capacity) {
if (_capacity <= 0) {
capacity
= 0;
return;
}
int n = 1;
while (n <_capacity) n<<=1;
capacity
= n;
storage_size
= capacity * 2 - 1;
mem
= new int[storage_size];
int k = 0;
while (k INT_MAX;
}
public:
SegmentTree(
int _capacity) {
init_mem(_capacity);
}
SegmentTree(vector
<int>::iterator begin, vector<int>::iterator end) {
capacity
= end - begin;
init_mem(capacity);
int k = capacity - 1;
vector
<int>::iterator iter = begin;
while (iter != end) mem[k++] = *iter++;
init_level_update();
}
~SegmentTree() {
delete[] mem;
}

// update value in original data index
void update(int idx, int val) {
if (idx >= capacity || idx <0) return;
int k = idx + capacity - 1; // internal storage index
mem[k] = val;
while (k > 0) {
k
= (k - 1) >> 1;
int L = (k <<1) + 1;
int R = L + 1;
mem[k]
= min (mem[L], mem[R]);
}
}

// retrive the min value in index range [a, b)
int query(int a, int b) {
return query(a, b, 0, 0, capacity);
}

void print_mem(const char* msg) {
cout
<endl;
for (int i=0; i<(capacity*2-1); i++) {
cout
<" ";
}
cout
<<endl;
}
};
void test(const char* msg, SegmentTree& seg_tree, int* data, int size) {
cout
<endl;
for (int i=0; i<=size; i++) {
for (int j=i+1; j<=size; j++) {
int tmin = seg_tree.query(i, j);
cout
<<"min of ("<","<") = "<endl;
int amin = INT_MAX;
for (int k=i; kif (data[k] data[k];
if (amin != tmin)
cout
<<"fail"<<endl;
else
cout
<<"ok"<<endl;
}
}
}
int main() {
int h[] = {6, 2, 5, 4, 5, 3, 6};
int size= sizeof(h) / sizeof(int);
vector
<int> hs(h, h + size); SegmentTree seg_tree(hs.begin(), hs.end());
test(
"Test construction with data :", seg_tree, h, size); SegmentTree init_empty_tree(size);
for (int i=0; i) init_empty_tree.update(i, h[i]);
test("Test construction without data", init_empty_tree, h, size); system("pause");
return 0;
}

 下面是一个带有返回最小值索引值的改进版本


bubuko.com,布布扣id="code_img_closed_58b3634b-6698-487c-badd-8aa7a3d97709" class="code_img_closed"
src="https://img.php1.cn/3cd4a/1eebe/cd5/bcafc120671304eb.webp">bubuko.com,布布扣 id="code_img_opened_58b3634b-6698-487c-badd-8aa7a3d97709"
class="code_img_opened" Onclick="cnblogs_code_hide(‘58b3634b-6698-487c-badd-8aa7a3d97709‘,event)"
src="https://img.php1.cn/3cd4a/1eebe/cd5/617c1173853af4b6.webp">

class SegmentTree {
private:
int *mem;
int *idx;
int capacity;
int storage_size;
private:
void init_level_update() {
int k = capacity - 1;
while (--k >= 0) {
int L = (k<<1) + 1;
int R = L + 1;
if (mem[L] < mem[R]) {
mem[k]
= mem[L];
idx[k]
= idx[L];
}
else {
mem[k]
= mem[R];
idx[k]
= idx[R];
}
}
}
pair
<int, int> query(int a, int b, int idx, int L, int R) {
if (b <= L || a >= R) return make_pair(INT_MAX, -1);
if (a <= L && R <= b) return make_pair(mem[idx], this->idx[idx]);
pair
<int, int> ml = query(a, b, (idx<<1) + 1, L, (L+R)/2);
pair
<int, int> mr = query(a, b, (idx<<1) + 2, (L+R)/2, R);
return ml.first ml : mr;
}
void init_mem(int _capacity) {
if (_capacity <= 0) {
capacity
= 0;
return;
}
int n = 1;
while (n <_capacity) n<<=1;
capacity
= n;
storage_size
= capacity * 2 - 1;
mem
= new int[storage_size];
idx
= new int[storage_size];

int k = 0;
while (k INT_MAX;
k = capacity - 1;
int i = 0;
while (k ;
}
public:
SegmentTree(
int _capacity) {
init_mem(_capacity);
}
SegmentTree(vector
<int>::iterator begin, vector<int>::iterator end) {
capacity
= end - begin;
init_mem(capacity);
int k = capacity - 1;
vector
<int>::iterator iter = begin;
while (iter != end) mem[k++] = *iter++;
init_level_update();
}
~SegmentTree() {
delete[] mem;
delete[] idx;
}
// update value in original data index
void update(int index, int val) {
if (index >= capacity || idx <0) return;
int k = index + capacity - 1; // internal storage index
mem[k] = val;
while (k > 0) {
k
= (k - 1) >> 1;
int L = (k <<1) + 1;
int R = L + 1;
if (mem[L] < mem[R]) {
mem[k]
= mem[L];
idx[k]
= idx[L];
}
else {
mem[k]
= mem[R];
idx[k]
= idx[R];
}
}
}
// retrive the min value in index range [a, b)
pair<int, int> query(int a, int b) {
return query(a, b, 0, 0, capacity);
}
void print_mem(const char* msg) {
cout
<endl;
for (int i=0; i<(capacity*2-1); i++) {
cout
<" ";
}

for (int i=0; i2 - 1; i++) {
cout
<",";
}
cout
<<endl;
}
};

View Code

 

参考:

  挑战程序设计竞赛第二版

Implementation:Segment Tree 线段树,布布扣,bubuko.com


推荐阅读
  • socket8 [命名管道]
    ::命名管道不但能实现同一台机器上两个进程通信,还能在网络中不同机器上的两个进程之间的通信机制。与邮槽不同,命名管道是采用基于连接并且可靠的传输方式,所以命名管道传输数据只能一对一 ... [详细]
  • 论文阅读及复现 | Improved Semantic Representations From TreeStructured Long ShortTerm Memory Networks
    两种形式的LSTM变体Child-SumTree-LSTMsN-aryTree-LSTMshttps:paperswithcode.compaperimproved-semanti ... [详细]
  • 【实践】基于RTThread的智慧路灯案例实验分享
    之前分享了基于LiteOS的智慧农业案例实验分享基于LiteOS的智慧农业案例实验分享,阅读量挺不错,看样子大家都挺喜欢这种实验。那咱们就再来一个类似的实验:基于RT-Thread ... [详细]
  • 步骤一:明确主打的核心目标用户群(对应产品侧的定位)这个核心目标用户群体是该产品成功挤进市场的切入点,甚至是撬动市场的支点和撬杠。市面上几乎很少有产品是专门给一个群体用而对其他群体 ... [详细]
  • #includestdafx.h#includeiostream#includesstream#includemap#includestring ... [详细]
  • rbac 4表 常规设计
    rbac4表常规设计设计模型:1、管理员表(users)Schema::create('users',function(Blueprint$table){$tabl ... [详细]
  • packagetest;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOE ... [详细]
  • vector:在vc6中,如果要镶嵌使用vector,如vector,后面的两个应该用,空格隔开,否则被编译器认为是移位符string::npos的值为 ... [详细]
  • Spark 贝叶斯分类算法
    一、贝叶斯定理数学基础我们都知道条件概率的数学公式形式为即B发生的条件下A发生的概率等于A和B同时发生的概率除以B发生的概率。根据此公式变换,得到贝叶斯公式:即贝叶斯定律是关于随机 ... [详细]
  • 安全3AAuthentication:认证Authorzation:授权Accouting|Audition:审计用户管理用户:UID:0,不一定是root,root的uid非0时 ... [详细]
  • 吴恩达“机器学习”——学习笔记二
    定义一些名词欠拟合(underfitting):数据中的某些成分未被捕获到,比如拟合结果是二次函数,结果才只拟合出了一次函数。过拟合(overfitting):使用过量的特征集合, ... [详细]
  • UDP协议开发
    UDP是用户数据报协议(UserDatagramProtocol,UDP)的简称,其主要作用是将网络数据流量压缩成数据报形式,提供面向事务的简单信息传送服务。与TCP协议不同,UD ... [详细]
  • Adapter相当于C(Controller,控制器),listView相当于V(View,视图)用于显示数据为ListView提供数据的List,数组或数据库相当于MVC模式中的 ... [详细]
  • 根据时间更改网站背景的脚本。热!
    我在网上找到了它,并以自己的方式对其进行了自定义;作者的功劳就在那里。实际上,这是一个用于更改背景颜色的脚本,并且在我看来& ... [详细]
  • 使用Mybatis框架操作数据库时,可以使用注解的方式,也可以使用XML文件配置,两种写法各有千秋。在使用注解进行save操作时,如果我想获取插入数据后的自增主键,那么可以使用如下 ... [详细]
author-avatar
x洗不掉的思念
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有