V

算法可视化

ZHEN
分享到微博分享到 XGitHub 仓库个人主页
学习工具算法复杂度速查算法学习路径
数据结构数组链表栈队列树堆哈希表图字典树并查集LRU 缓存跳表线段树B+ 树布隆过滤器树状数组
经典排序算法冒泡排序鸡尾酒排序双调排序选择排序插入排序二分插入排序希尔排序归并排序自顶向下归并快速排序三路快排双轴快排堆排序计数排序基数排序桶排序
图算法Dijkstra 最短路Kruskal 最小生成树Prim 最小生成树Bellman-Ford 最短路拓扑排序Floyd 多源最短路强连通分量2-SAT最大流二分图匹配LCA 倍增欧拉路径
动态规划编辑距离0-1 背包完全背包最长公共子序列最长递增子序列硬币找零方案数石子合并旅行商 TSP树形 DP数位 DP换根 DP
回溯与搜索N 皇后子集生成全排列组合总和迷宫寻路岛屿数量单词搜索数独A* 寻路
字符串KMP 字符串匹配Rabin-KarpBoyer-MooreManacher后缀数组LCP / height 数组AC 自动机Z 函数
数学与数论埃氏筛线性筛欧几里得算法快速幂扩展欧几里得中国剩余定理欧拉函数米勒-拉宾FFTPollard's Rho
计算几何凸包旋转卡壳最近点对线段相交扫描线求交
查找二分查找二分边界旋转数组搜索二分答案三分查找

线段树 Segment Tree

数据结构 · 每个节点管一段区间,存这段的聚合

什么是线段树

要反复求「数组某一段的和(或最值)」,逐个累加是 O(n),区间一长就慢。线段树把数组建成一棵二叉树:每个节点管一段区间、存这段的聚合值(这里用和)。根管整个数组,往下对半分,叶子是单个元素——父节点的和正好是左右孩子之和。

这里给 8 个数 [2, 5, 1, 4, 9, 3, 7, 6] 建了一棵求和线段树(共 15 个节点,根的和是 37)。填两个下标 a、b:点「区间和」看它怎么把一段拆成几个「现成的整段」相加;点「更新」把第 a 个元素改成 b,看改一个数只牵动一条叶→根的路径。

亲手试试
37122575121325149376

选一段区间点「区间和」——看它把区间拆成几个「现成的整段」相加,而不是逐个累加。

区间查询的诀窍:把目标区间拆成 O(log n) 个「正好被某个节点完整覆盖」的整段,直接取它们存好的和,不必逐个累加。单点更新也只动叶子到根的一条路径,同样 O(log n)。要做区间整体修改(比如把一段都加 5),还能配「懒标记」把更新延迟下推、批量处理。

另有一个更省空间的同类结构——树状数组(Fenwick / BIT),用一维数组 + lowbit 巧算前缀和,代码更短更省内存,但不如线段树直观、也没这么通用(线段树能装和、最值、最大子段和等各种聚合)。

线段树在哪里用

区间和 / 区间最值 / 区间统计:反复查询又夹杂修改的场景。
算法竞赛重器:区间问题的标配,配懒标记还能区间修改。
数据库 / 时序聚合:按区间汇总指标的底层思路。

它把「树 + 数组聚合」用到了极致——也是这趟结构之旅里很硬核的一站。