数据结构之——线段树简介(持续更新🔥)

234 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」第10天,点击查看活动详情

线段树的定义

将一段线性的区间(线段)分成许多的子区间,每个子区间都对应着线段树中的一个结点。

这种 结点是一段区间的数据结构就叫做线段树

线段树的建立

我们线段树的根节点代表着整条线段的结点,

倘若线段树根节点代表的线段是[1,16],则线段左边界L=1,右边界R=16;

我们分割左右边界是先算出中间值:;(遵循C/C++整形除法的向下取整)

即左孩子代表区间为: [1, ] ------> [1 , 8]

右孩子代表区间为 :[, 16]------> [9 , 16]

对于每个结点,我们将它代表的区间(线段)平均的分为两个小区间,从而建立左右孩子,以此类推

区间会越分越小,直到分出来的子区间L==R,长度为1,这时候便无法再分

线段树的强大功能

线段树功能强大,是算法竞赛中在特定情况下可以大幅减少时间复杂度的数据结构

它支持区间求和区间最大值区间公约数区间修改单点修改等操作,

正是因为它每次搜索都会将每段区间平分为2的性质,单点修改与查询的时间复杂度可以优化到O(log2n)

但是,线段树也不是万能的,有且仅当可以用线段树维护的问题满足区间加法

否则,将无法把每个大问题分为小问题来解决

线段树可以维护的数据类型

上文讲到,线段树只支持解决区间加法问题。那么,何为区间加法

满足区间加法的问题,当前仅当

对于 区间结果可以由区间和区间 , 的结果合并而来.

即可以将一段区间上的问题,任意地分割为两个小区间来解决,原则上无需平分,最小的区间长度为1

简单的经典区间加法问题

  1. 区间求和

  1. 区间最大值

注:不满足区间加法的问题有:

  1. 区间的众数;
  2. 区间的最长不下降子序列。