线段树也是一种可使用表结构实现的概念上的树形结构,这种方式建立过程如二叉堆中计算节点的左孩子与右孩子一样,但线段树一定是一颗完全二叉树,所以空间复杂度为 $ O(2 * n) $,$ n $ 表示数组大小。重点是要读懂线段树表示是什么意思。
示例:

释义:
根节点 5 --- [0,6] 表示在数组 $ {18,17,13,19,15,11,20} $ 区间 [0,6] 内最小值为数组下标5的数。
其他节点含义同上。。。
下面是代码实现:
#include <iostream>
#define LC(i) ((i) << 1)
#define RC(i) ((i) << 1 | 1)
#define M 10010
#define min(a, b) ((a) < (b) ? (a) : (b))
struct { int l, r, val; } SegTree[M];
int num[] = { 18, 17, 19, 13, 15, 11, 20 };
void build(int l, int r, int k)
{
if (l == r)
SegTree[k].val = num[l];
else
{
int m = (l + r) >> 1;
build(l, m, LC(k));
build(m + 1, r, RC(k));
SegTree[k].val = min(SegTree[LC(k)].val, SegTree[RC(k)].val);
}
}
void update(int l, int r, int k, int pos, int v)
{
if (l > pos || r < pos || r < l)
return;
if (l == r)
{
SegTree[k].val = v;
return;
}
int m = (l + r) >> 1;
if (pos <= m)
update(l, m, LC(k), pos, v);
else
update(m + 1, r, RC(k), pos, v);
SegTree[k].val = min(SegTree[LC(k)].val, SegTree[RC(k)].val);
}
int query(int l, int r, int x, int y, int k)
{
if (l > r || l > y || r < x)
return M;
if (x <= l && r <= y)
return SegTree[k].val;
int m = (l + r) >> 1;
return min(query(l, m, x, y, LC(k)), query(m + 1, r, x, y, RC(k)));
}
int main()
{
int len, x, y, k, v;
len = (sizeof(num) / sizeof(int)) - 1;
build(0, len, 1);
for (int i = 1; i <= 2 * len; i++)
std::cout << SegTree[i].val << ' ';
std::cout << std::endl;
std::cout << "查询[x,y]区间的最小值:" << std::endl;
std::cin >> x >> y;
std::cout << query(0, len, x, y, 1) << std::endl;
std::cout << "更新下标k位置上的值:" << std::endl;
std::cin >> k >> v;
update(0, len, 1, k, v);
for (int i = 1; i <= 2 * len; i++)
std::cout << SegTree[i].val << ' ';
std::cout << std::endl;
return 0;
}
参考:
https://github.com/darkchii/cosmos/blob/master/code/data_structures/src/tree/segment_tree/segment_Tree_rmq.adb
http://www.cnblogs.com/TenosDoIt/p/3453089.html