线段树(Segment Tree)是一种常用的数据结构,用于处理区间查询问题,例如区间最值、区间和等。它将整个区间递归地划分成一系列的子区间,并为每个子区间维护一些信息,例如区间的最值或者区间的和。
以下是一个简单的线段树的 C++ 实现,用于求区间和:
#include <vector>
class SegmentTree {
private:
std::vector<int> tree;
int n; // 数组的大小
// 构建线段树
void buildTree(const std::vector<int>& nums, int node, int left, int right) {
if (left == right) {
tree[node] = nums[left]; // 叶子节点
} else {
int mid = left + (right - left) / 2;
buildTree(nums, 2 * node, left, mid); // 构建左子树
buildTree(nums, 2 * node + 1, mid + 1, right); // 构建右子树
tree[node] = tree[2 * node] + tree[2 * node + 1]; // 更新父节点
}
}
// 区间查询辅助函数
int queryHelper(int node, int start, int end, int left, int right) {
if (start > right || end < left) {
return 0; // 区间完全不重叠,返回0
}
if (left <= start && end <= right) {
return tree[node]; // 区间完全包含在目标区间中,返回节点值
}
int mid = start + (end - start) / 2;
return queryHelper(2 * node, start, mid, left, right) +
queryHelper(2 * node + 1, mid + 1, end, left, right); // 递归查询左右子树
}
public:
SegmentTree(const std::vector<int>& nums) {
n = nums.size();
tree.resize(4 * n); // 线段树的大小为原数组大小的4倍
buildTree(nums, 1, 0, n - 1); // 从根节点开始构建线段树
}
// 区间查询
int query(int left, int right) {
return queryHelper(1, 0, n - 1, left, right);
}
};
int main() {
std::vector<int> nums = {1, 3, 5, 7, 9, 11};
SegmentTree st(nums);
// 查询区间 [1, 4] 的和
std::cout << "Sum of elements in range [1, 4]: " << st.query(1, 4) << std::endl;
return 0;
}
在这个示例中,我们定义了一个 SegmentTree 类来实现线段树。构造函数接受一个整数数组 nums 作为输入,并根据该数组构建线段树。buildTree() 函数用于构建线段树,它采用递归的方式,将整个区间划分成子区间,并为每个子区间维护一些信息。query() 函数用于查询指定区间 [left, right] 的和,它通过调用辅助函数 queryHelper() 来递归地查询左右子树并返回结果。