c++实现线段树

179 阅读2分钟

线段树(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() 来递归地查询左右子树并返回结果。