数据结构--树--线段树(Segment Tree)

文章目录

    • 1. 概念
    • 2. 建树
    • 3. 查询
    • 4. 修改
    • 5. 完整代码及测试

在这里插入图片描述

上图 from 熊掌搜索

  • 类似数据结构:树状数组

1. 概念

线段树是一种二叉树,是用来表示一个区间的树:

  • 常常用来查询区间的:和、最小值、最大值
  • 树结点中存放不是普通二叉树的值,其结点结构如下
class TreeNode
{
public:int sum;//区间和int MAX;//区间最大的int MIN;//区间最小的int start, end;//区间左右端点TreeNode *left, *right;//左右节点TreeNode(int s, int e, int v):start(s),end(e),sum(v){left = right = NULL;MAX = v;MIN = v;}
};

2. 建树

  • 传入数组,及其左右极限端点
  • 自底向上建树
	TreeNode* build(vector<int>& A, int L, int R){if(L > R)return NULL;TreeNode* rt = new TreeNode(L,R,A[L]);if(L == R)return rt;int mid = L+((R-L)>>1);//对半分开rt->left = build(A,L,mid);rt->right = build(A,mid+1,R);rt->sum = 0;if(rt->left){rt->sum += rt->left->sum;rt->MAX = max(rt->MAX, rt->left->MAX);rt->MIN = min(rt->MIN, rt->left->MIN);}if(rt->right){rt->sum += rt->right->sum;rt->MAX = max(rt->MAX, rt->right->MAX);rt->MIN = min(rt->MIN, rt->right->MIN);}return rt;}

3. 查询

  • 时间复杂度:O(log⁡n)O(\log n)O(logn)
	vector<int> query(TreeNode *rt, int s, int e)//查询区间的sum,min,max{if(s > rt->end || e < rt->start)return {0, INT_MAX, INT_MIN};//没有交集if(s <= rt->start && rt->end <= e)return {rt->sum, rt->MIN, rt->MAX};//完全包含区间,取其值//不完全包含,左右查找vector<int> l = query(rt->left, s, e);vector<int> r = query(rt->right,s, e);//汇总信息vector<int> summary(3);summary[0] = l[0] + r[0];summary[1] = min(l[1], r[1]);summary[2] = max(l[2], r[2]);return summary;}

4. 修改

  • 时间复杂度:O(log⁡n)O(\log n)O(logn)
	void modify(TreeNode *rt, int id, int val){if(rt->start == rt->end){	//叶子节点rt->sum = val;//和为自身rt->MAX = val;rt->MIN = val;data[id] = val;return;}int mid = (rt->start + rt->end)/2;if(id > mid)modify(rt->right, id, val);elsemodify(rt->left, id, val);root->sum = 0;if(rt->left){rt->sum += rt->left->sum;rt->MAX = max(rt->MAX, rt->left->MAX);rt->MIN = min(rt->MIN, rt->left->MIN);}if(rt->right){rt->sum += rt->right->sum;rt->MAX = max(rt->MAX, rt->right->MAX);rt->MIN = min(rt->MIN, rt->right->MIN);}}

5. 完整代码及测试

/*** @description: 线段树* @author: michael ming* @date: 2020/3/13 0:21* @modified by:* @Website: https://michael.blog.csdn.net/*/
#include<vector>
#include<iostream>
#include<climits>
using namespace std;
class TreeNode
{
public:int sum;//区间和int MAX;//区间最大的int MIN;//区间最小的int start, end;//区间左右端点TreeNode *left, *right;//左右节点TreeNode(int s, int e, int v):start(s),end(e),sum(v){left = right = NULL;MAX = v;MIN = v;}
};
class SegmentTree
{
public:TreeNode* root;vector<int> data;SegmentTree(vector<int>& A){root = build(A, 0, A.size()-1);data = A;}~SegmentTree(){destroy(root);}void destroy(TreeNode* rt){if(!rt) return;destroy(rt->left);destroy(rt->right);delete rt;}TreeNode* build(vector<int>& A, int L, int R){if(L > R)return NULL;TreeNode* rt = new TreeNode(L,R,A[L]);if(L == R)return rt;int mid = L+((R-L)>>1);//对半分开rt->left = build(A,L,mid);rt->right = build(A,mid+1,R);rt->sum = 0;if(rt->left){rt->sum += rt->left->sum;rt->MAX = max(rt->MAX, rt->left->MAX);rt->MIN = min(rt->MIN, rt->left->MIN);}if(rt->right){rt->sum += rt->right->sum;rt->MAX = max(rt->MAX, rt->right->MAX);rt->MIN = min(rt->MIN, rt->right->MIN);}return rt;}vector<int> query(TreeNode *rt, int s, int e)//查询区间的sum,min,max{if(s > rt->end || e < rt->start)return {0, INT_MAX, INT_MIN};//没有交集if(s <= rt->start && rt->end <= e)return {rt->sum, rt->MIN, rt->MAX};//完全包含区间,取其值//不完全包含,左右查找vector<int> l = query(rt->left, s, e);vector<int> r = query(rt->right,s, e);//汇总信息vector<int> summary(3);summary[0] = l[0] + r[0];summary[1] = min(l[1], r[1]);summary[2] = max(l[2], r[2]);return summary;}void modify(TreeNode *rt, int id, int val){if(rt->start == rt->end){	//叶子节点rt->sum = val;//和为自身rt->MAX = val;rt->MIN = val;data[id] = val;return;}int mid = (rt->start + rt->end)/2;if(id > mid)modify(rt->right, id, val);elsemodify(rt->left, id, val);root->sum = 0;if(rt->left){rt->sum += rt->left->sum;rt->MAX = max(rt->MAX, rt->left->MAX);rt->MIN = min(rt->MIN, rt->left->MIN);}if(rt->right){rt->sum += rt->right->sum;rt->MAX = max(rt->MAX, rt->right->MAX);rt->MIN = min(rt->MIN, rt->right->MIN);}}
};
//-------------test---------------------
void printVec(vector<int> &a)
{for(auto& ai : a)cout << ai << " ";cout << endl;
}int main()
{vector<int> v = {1,2,7,8,5};printVec(v);cout << "建立线段树" << endl;SegmentTree sgtree(v);printVec(sgtree.data);cout << "查询区间的sum,MIN,MAX" << endl;vector<int> qy_res = sgtree.query(sgtree.root,1,3);printVec(qy_res);cout << "修改某位置的值" << endl;sgtree.modify(sgtree.root,1,100);printVec(sgtree.data);cout << "查询区间的sum,MIN,MAX" << endl;qy_res = sgtree.query(sgtree.root,1,3);printVec(qy_res);return 0;
}

运行结果:valgrind ./a.out

==16895== Memcheck, a memory error detector
==16895== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==16895== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==16895== Command: ./a.out
==16895== 
1 2 7 8 5 
建立线段树
1 2 7 8 5 
查询区间的sum,MIN,MAX
17 2 8 
修改某位置的值
1 100 7 8 5 
查询区间的sum,MIN,MAX
115 7 100 
==16895== 
==16895== HEAP SUMMARY:
==16895==     in use at exit: 0 bytes in 0 blocks
==16895==   total heap usage: 29 allocs, 29 frees, 616 bytes allocated
==16895== 
==16895== All heap blocks were freed -- no leaks are possible
==16895== 
==16895== For counts of detected and suppressed errors, rerun with: -v
==16895== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
  • 相关题目:LintCode 207. 区间求和 II(hard)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/477067.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

神经网络可视化有3D版本了,美到沦陷!(已开源)

源 |量子位做计算机视觉&#xff0c;离不开CNN。可是&#xff0c;卷积、池化、Softmax……究竟长啥样&#xff0c;是怎样相互连接在一起的&#xff1f;对着代码凭空想象&#xff0c;多少让人有点头皮微凉。于是&#xff0c;有人干脆用Unity给它完整3D可视化了出来。还不光是有个…

CentOS6上Hadoop集群中服务器cpu sys态异常的定位与解决

问题现象 在zabbix系统中&#xff0c;对Hadoop集群的历史监控数据分析时&#xff0c;发现在执行大Job任务时&#xff0c;某些服务节点的cpu sys态很高&#xff1b;具体以hadoop_A服务节点为例&#xff0c;在10:15-10:40这个时间段&#xff0c;cpu user态为60%&#xff0c;而sys…

偶也Blog了

欢迎大家和我交流…………转载于:https://www.cnblogs.com/dsclub/archive/2004/06/18/16753.html

LintCode 1692. 组队打怪(田忌赛马,二分查找)

1. 题目 你现在有n个英雄&#xff0c;每个英雄的战斗力为 atk1,你要用这些英雄去对付n个怪物&#xff0c;每个怪物的战斗力为atk2。 在一场战斗中&#xff0c;你需要安排每个英雄分别与一个怪兽战斗&#xff0c;如果英雄战斗力高于怪兽&#xff0c;那个怪兽就会被击杀&#xf…

谷歌搜索,全球宕机??

文 | 好困源 | 新智元忽然之间&#xff0c;谷歌搜索&#xff0c;挂了。美东时间周一晚上9点&#xff08;北京时间周二早上9点&#xff09;左右&#xff0c;有不少用户突然发现自己上不去谷歌了。对于这次谷歌的突然宕机&#xff0c;网友们完全没有任何的心理准备。「谷歌停止工…

.NET建模

.NET建模 Deborah Melewski, Jack Vaughan[2004/1/1] 建模和软件设计又将迎来新一波的高峰。UML和模型驱动架构MDA目前在业界越发引人注目&#xff0c;清晰地进行前置设计&#xff08;design up front&#xff0c;译者注&#xff1a;这是过去批判得比较多的&#xff0c;是瀑布…

基于Flume的美团日志收集系统(一)架构和设计

背景 美团的日志收集系统负责美团的所有业务日志的收集&#xff0c;并分别给Hadoop平台提供离线数据和Storm平台提供实时数据流。美团的日志收集系统基于Flume设计和搭建而成。 《基于Flume的美团日志收集系统》将分两部分给读者呈现美团日志收集系统的架构设计和实战经验。 第…

LintCode 1690. 朋友推荐(二分插入)

1. 题目 某交友网站会给除了第一个用户以外的每个新注册的用户推荐一位之前已经注册过并且性格值和他最相近的用户&#xff0c;如果有多人满足条件则选择性格值较小的。 给定数组val[]表示按时间顺序注册的 n 位用户的性格值&#xff0c;输出一个大小为 n-1 的数组&#xff0…

WinForm与脚本的交互

这是去年学习SmartClient时写下的&#xff0c;有兴趣可以看看 将Winform Control嵌入IE,很多时候需要JS脚本与Control进行交互。一方面是在脚本中使用控件的属性&#xff0c;调用控件的方法&#xff0c;另外一方面是脚本中能够响应控件的事件。对于第一个问题较为简单&#…

我用AI大模型帮我写公众号赚钱!

文 |卖萌酱大家好&#xff0c;我是卖萌酱。最近太忙了&#xff0c;有很多想写的文章&#xff0c;但实在精力匮乏。怎么办&#xff0c;不能停更吧&#xff1f;就在这时&#xff0c;卖萌酱听到了一个新名词&#xff1a;AIGC。什么意思呢&#xff1f;我们知道互联网上的早期内容&a…

Nacos部署中的一些常见问题汇总

开个帖子&#xff0c;汇总一下读者经常提到的一些问题 问题一&#xff1a;Ubuntu下启动Nacos报错 问题描述 使用命令sh startup.sh -m standalone启动报错&#xff1a; ./startup.sh: 78: ./startup.sh: [[: not found./startup.sh: 88: ./startup.sh: [[: not found./startu…

土木工程正在沦为“天坑”专业…

文 | 羿阁&#xff08;发自凹非寺&#xff09;源 | 量子位一份转专业录用名单&#xff0c;直接把土木工程推向了舆论焦点。事情是这样的。前不久&#xff0c;湖南大学公示了2022年本科生转专业的一份名单。然后网友们惊奇地发现&#xff0c;土木工程学院共转出98人&#xff0c;…

Spring Cloud Alibaba基础教程:Nacos的集群部署

前情回顾&#xff1a; 《Spring Cloud Alibaba基础教程&#xff1a;使用Nacos实现服务注册与发现》《Spring Cloud Alibaba基础教程&#xff1a;支持的几种服务消费方式》《Spring Cloud Alibaba基础教程&#xff1a;使用Nacos作为配置中心》《Spring Cloud Alibaba基础教程&a…

智能客户端研究笔记(三)

本文大量引用了别人的文章&#xff0c;引用自http://www.microsoft.com/china/community/program/originalarticles/TechDoc/smartclient.mspx发布程序 1、在发布和更新服务器上设置一个虚拟目录&#xff08;如&#xff1a;SmartClient&#xff09;将应用组件的所有文件放置…

3月14日 我用Python几十行代码为女朋友画了一个爱心

今天是个特殊的日子&#xff0c;圆周率日&#xff0c;哈哈&#xff01;来对你爱的人表达爱吧&#xff01; 女朋友就是我爱人啦&#xff01;&#x1f601; # -*- coding:utf-8 -*- # Python Version: 3.7 # Time: 2020/3/14 13:14 # Author: Michael Ming # Website: https://m…

Pytorch显存分配机制与显存占用分析方法

文 | Connolly知乎&#xff08;已授权&#xff09;源 | 极市平台作者最近两年在研究分布式并行&#xff0c;经常使用PyTorch框架。一开始用的时候对于PyTorch的显存机制也是一知半解&#xff0c;连蒙带猜的&#xff0c;经常来知乎上来找答案&#xff0c;那么我就吸收大家的看法…

Spring Cloud Stream 使用延迟消息实现定时任务(RabbitMQ)

应用场景 我们在使用一些开源调度系统&#xff08;比如&#xff1a;elastic-job等&#xff09;的时候&#xff0c;对于任务的执行时间通常都是有规律性的&#xff0c;可能是每隔半小时执行一次&#xff0c;或者每天凌晨一点执行一次。然而实际业务中还存在另外一种定时任务&am…

LeetCode 1380. 矩阵中的幸运数(set)

1. 题目 给你一个 m * n 的矩阵&#xff0c;矩阵中的数字 各不相同 。请你按 任意 顺序返回矩阵中的所有幸运数。 幸运数是指矩阵中满足同时下列两个条件的元素&#xff1a; 在同一行的所有元素中最小在同一列的所有元素中最大 示例 1&#xff1a; 输入&#xff1a;matrix …

GARFIELD@10-07-2004

tit for tat转载于:https://www.cnblogs.com/rexhost/archive/2004/10/07/49560.html

DeepMind 发了篇论文,把我看笑了

文 | severus近日&#xff0c;曾开发出举世瞩目的 AlphaGo 的 DeepMind&#xff0c;在 ArXiv 上发表了一篇文章&#xff0c;名为&#xff1a;Meaning without reference in large language models文中提到&#xff0c;大参数规模的语言模型是已经具备了部分类人智能的&#xff…