C++ 线段树 高级数据结构

线段树是一种平衡二叉搜索树(完全二叉树),它将一个线段区间划分成一些单元区间。对于线段树中的每一个非叶子节点[a,b],他的左儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/2+1,b],最后的叶子节点数目为N,与数组下标对应。线段树的一般包括建立、查询、插入、更新等操作,建立规模为N的时间复杂度是O(NlogN),其他操作时间复杂度为O(logN)。

平衡二叉搜索树(完全二叉树)是指除了最后一层,其他层都是满的二叉树。
线段树最大的价值是平衡,因为线段树是平衡二叉树。很多题目可以通过平衡二叉树达到完美的时间复杂度。

#include <vector>
//线段树的构造
void build_segment_tree(std::vector<int>& nums, std::vector<int>& value, int pos, int left, int right)
{
 if (left==right)
 {
  value[pos] = nums[left];
  return;
 }
 int mid = (left + right) / 2;
 build_segment_tree(nums, value, 2 * pos + 1, left, mid);
 build_segment_tree(nums, value, 2 * pos + 2, mid+1, right);
 value[pos] = value[2 * pos + 1] + value[2 * pos + 2];
}
//线段树的遍历
void print_segment_tree(std::vector<int>& value, int pos, int left, int right, int layer)
{
 for (int i = 0; i < layer; i++)
 {
  printf("---");
 }
 printf("[%d  %d] [%d]:   %d\n", left, right, pos, value[pos]);
 if (left==right)
 {
  return;
 }
 int mid = (left + right) / 2;
 print_segment_tree(value, 2 * pos + 1, left, mid, layer + 1);
 print_segment_tree(value, 2 * pos + 2, mid + 1, right, layer + 1);
}
//线段树的求和
int sum_range_segment_tree(std::vector<int>& value, int pos, int left, int right, int qleft, int qright)
{
 if (qleft>right||qright<left)
 {
  return 0;
 }
 if (qleft<=left&&qright>=right)
 {
  return value[pos];
 }
 int mid = (left + right) / 2;
 return sum_range_segment_tree(value, 2 * pos + 1, left, mid, qleft, qright) + sum_range_segment_tree(value, 2 * pos + 2, mid + 1, right, qleft, qright);
}
//线段树的更新
void update_segment_tree(std::vector<int>& value, int pos, int left, int right, int index, int new_value)
{
 if (left==right&&left==index)
 {
  value[pos] = new_value;
  return;
 }
 int mid = (left + right) / 2;
 if (index<=mid)
 {
  update_segment_tree(value, 2*pos+1, left, mid, index, new_value);
 }
 else
 {
  update_segment_tree(value, 2 * pos + 2, mid+1, right, index, new_value);
 }
 value[pos] = value[2 * pos + 1] + value[2 * pos + 2];
}
int main()
{
 std::vector<int> nums;
 for (int i = 0; i < 6; i++)
 {
  nums.push_back(i);
 }
 std::vector<int> value;
 for (int i = 0; i < 24; i++)
 {
  value.push_back(0);
 }
 build_segment_tree(nums, value, 0, 0, nums.size() - 1);
 printf("segment tree:\n");
 print_segment_tree(value, 0,0,nums.size()-1,0);
 int sum_range = sum_range_segment_tree(value, 0, 0, nums.size() - 1, 2, 4);
 printf("sum_range [2,5]=%d\n", sum_range);
 update_segment_tree(value, 0, 0, nums.size() - 1, 2, 10);
 printf("segment_tree:\n");
 print_segment_tree(value,0,0,nums.size()-1,0);
 return 0;
}

运行结果为:

segment tree:
[0  5] [0]:   15
---[0  2] [1]:   3
------[0  1] [3]:   1
---------[0  0] [7]:   0
---------[1  1] [8]:   1
------[2  2] [4]:   2
---[3  5] [2]:   12
------[3  4] [5]:   7
---------[3  3] [11]:   3
---------[4  4] [12]:   4
------[5  5] [6]:   5
sum_range [2,5]=9
segment_tree:
[0  5] [0]:   23
---[0  2] [1]:   11
------[0  1] [3]:   1
---------[0  0] [7]:   0
---------[1  1] [8]:   1
------[2  2] [4]:   10
---[3  5] [2]:   12
------[3  4] [5]:   7
---------[3  3] [11]:   3
---------[4  4] [12]:   4
------[5  5] [6]:   5
发布了135 篇原创文章 · 获赞 121 · 访问量 4883

猜你喜欢

转载自blog.csdn.net/weixin_44208324/article/details/105196742
今日推荐