上一篇是用ST算法实现区间最值查询,线段树也可以实现相应的功能。其实在处理大量数据的时候,线段树的适用范围更加广泛,不仅是最值查询,任何关于区间问题的题目都可以利用线段树解决。
#include<iostream>
using namespace std;
#define MAXN 100
#define MAXIND 256 //线段树节点个数
//构建线段树,目的:得到M数组.
void initialize(int node, int b, int e, int M[], int A[])
{
if (b == e)
M[node] = b; //只有一个元素,只有一个下标
else
{
//递归实现左孩子和右孩子
initialize(2 * node, b, (b + e) / 2, M, A);
initialize(2 * node + 1, (b + e) / 2 + 1, e, M, A);
//search for the minimum value in the first and
//second half of the interval
if (A[M[2 * node]] <= A[M[2 * node + 1]])
M[node] = M[2 * node];
else
M[node] = M[2 * node + 1];
}
}
//找出区间 [i, j] 上的最小值的索引
int query(int node, int b, int e, int M[], int A[], int i, int j)
{
int p1, p2;
//查询区间和要求的区间没有交集
if (i > e || j < b)
return -1;
//if the current interval is included in
//the query interval return M[node]
if (b >= i && e <= j)
return M[node];
//compute the minimum position in the
//left and right part of the interval
p1 = query(2 * node, b, (b + e) / 2, M, A, i, j);
p2 = query(2 * node + 1, (b + e) / 2 + 1, e, M, A, i, j);
//return the position where the overall
//minimum is
if (p1 == -1)
return M[node] = p2;
if (p2 == -1)
return M[node] = p1;
if (A[p1] <= A[p2])
return M[node] = p1;
return M[node] = p2;
}
int main()
{
int M[MAXIND]; //下标1起才有意义,保存下标编号节点对应区间最小值的下标.
memset(M,-1,sizeof(M));
int a[]={3,1,5,7,2,9,0,3,4,5};
printf("%d\n",sizeof(a)/sizeof(a[0])-1);
initialize(1, 0, sizeof(a)/sizeof(a[0])-1, M, a);
cout<<query(1, 0, sizeof(a)/sizeof(a[0])-1, M, a, 0, 5)<<endl;
return 0;
}