在算法竞赛和实际工程开发中,我们经常需要对一个数组进行频繁的区间查询(如求区间和、最大值等)和单点或区间更新。如果每次都暴力遍历区间,时间复杂度会很高(O(n) 每次操作)。这时,C语言线段树就派上用场了!
线段树是一种二叉树结构,能够将区间操作的时间复杂度优化到 O(log n),是处理区间问题的利器。本教程将带你从零开始,用 C 语言一步步实现一个支持区间求和和单点更新的线段树。
线段树(Segment Tree)是一种用于存储区间信息的数据结构教程中的经典结构。它将一个大区间递归地划分为两个子区间,直到每个叶子节点代表原数组中的一个元素。

例如,对于数组 [1, 3, 5, 7, 9, 11],线段树的根节点保存的是整个区间的和(1+3+5+7+9+11=36),其左子树保存 [0,2] 的和,右子树保存 [3,5] 的和,以此类推。
线段树主要支持两种操作:
下面是一个完整的 C 语言线段树实现,支持区间求和与单点更新:
#include <stdio.h>#include <stdlib.h>#define MAXN 100000 // 假设数组最大长度int arr[MAXN]; // 原始数组int tree[4 * MAXN]; // 线段树数组(通常开4倍空间)// 构建线段树void build(int node, int start, int end) { if (start == end) { // 叶子节点 tree[node] = arr[start]; } else { int mid = (start + end) / 2; // 递归构建左右子树 build(2 * node, start, mid); build(2 * node + 1, mid + 1, end); // 当前节点值 = 左子树 + 右子树 tree[node] = tree[2 * node] + tree[2 * node + 1]; }}// 区间查询 [l, r]int query(int node, int start, int end, int l, int r) { if (r < start || end < l) { // 当前区间与查询区间无交集 return 0; } if (l <= start && end <= r) { // 当前区间完全包含在查询区间内 return tree[node]; } // 否则递归查询左右子树 int mid = (start + end) / 2; int left_sum = query(2 * node, start, mid, l, r); int right_sum = query(2 * node + 1, mid + 1, end, l, r); return left_sum + right_sum;}// 单点更新:将 arr[idx] 改为 valvoid update(int node, int start, int end, int idx, int val) { if (start == end) { // 找到叶子节点 arr[idx] = val; tree[node] = val; } else { int mid = (start + end) / 2; if (idx <= mid) { // 在左子树中更新 update(2 * node, start, mid, idx, val); } else { // 在右子树中更新 update(2 * node + 1, mid + 1, end, idx, val); } // 更新当前节点 tree[node] = tree[2 * node] + tree[2 * node + 1]; }}// 示例主函数int main() { int n = 6; arr[0] = 1; arr[1] = 3; arr[2] = 5; arr[3] = 7; arr[4] = 9; arr[5] = 11; build(1, 0, n - 1); // 构建线段树 printf("区间 [1, 3] 的和: %d\n", query(1, 0, n - 1, 1, 3)); // 输出 15 update(1, 0, n - 1, 2, 10); // 将 arr[2] 改为 10 printf("更新后,区间 [1, 3] 的和: %d\n", query(1, 0, n - 1, 1, 3)); // 输出 20 return 0;}4 * MAXN)。线段树广泛应用于需要高效区间查询和更新的场景,例如:
通过本教程,你已经掌握了如何用 C 语言实现一个基础的线段树。线段树是数据结构教程中的重要内容,也是提升算法能力的关键工具。熟练掌握后,你可以进一步学习懒标记(Lazy Propagation)以支持高效的区间更新操作。
记住,C语言线段树的核心在于理解其递归结构和区间划分逻辑。多写几遍代码,你就能轻松应对各种区间查询问题!
本文由主机测评网于2025-12-04发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025123034.html