线段树的概念与算法
前言
线段树是一种二叉搜索树,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点。线段树具有以下性质:
- 线段树的每个结点代表一个区间;
- 线段树的每个叶结点代表一个长度为1的区间;
- 线段树的每个非叶结点代表一个长度大于1的区间;
- 线段树的每个非叶结点的左子树代表一个左半区间,右子树代表一个右半区间;
拥有这种性质的搜索树,时间复杂度是O(logn),所以线段树是一种高效的数据结构。
这里,我们用数组来表示线段树,其中数组下标代表结点编号,结点下标为i的结点,其左子结点下标为2i+1,右子结点下标为2i+2。
本文子问题是记录区间最小值,所以线段树结点中存储的是区间最小值。
线段树的构建
线段树的构建过程如下:
- 确定线段树的深度,即log2(n)向上取整;
- 创建线段树,每个结点包含一个区间和两个子结点;
代码
1 | void build(vector<int> &arr, int start, int end, int id) { |
线段树的更新
线段树的更新过程如下:
- 找到需要更新的结点;
- 更新结点的值;
- 更新父结点的值;
代码
1 | void update(int start, int end, int id, int index, int val) { |
线段树的查询
线段树的查询过程如下:
- 找到需要查询的区间;
- 查询区间内的最小值;
代码
1 | int query(int start, int end, int id, int L, int R) { |
总结
这里是基本的线段树算法,如果需要更复杂的操作,可以在此基础上进行扩展。这里暂不赘述。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 迷路的小朋友!
评论





