1 #include <iostream>
2
3 using namespace std;
4 #define MAX_LEN 1000
5 //线段树是用来对区间内的数进行但单点修改,区间求和的 主要有的函数创建树的函数 创建单点修改的函数 创建区间求和的函数 都用到了递归的思想
6 void build_tree(int arr[],int tree[],int node,int start,int end) //给区间定范围
7 {
8 if(start==end)
9 tree[node]=arr[start];
10 else{
11 int left_node=2*node+1;
12 int right_node=2*node+2;
13 int mid=(start+end)/2;
14 build_tree(arr,tree,left_node,start,mid);
15 build_tree(arr,tree,right_node,mid+1,end); //到此,左右节点的值就算出来了
16 tree[node]=tree[left_node]+tree[right_node];
17 }
18 }
19 void update_tree(int arr[],int tree[],int node,int start,int end,int idx,int val) //表示把arr[idx]=val 单点修改
20 {
21 if(start==end)
22 {
23 arr[idx]=val;
24 tree[node]=val;
25 }
26 else
27 {
28 int mid=(start+end)/2;
29 int left_node=2*node+1;
30 int right_node=2*node+2;
31 if(idx>=start&&idx<=mid)
32 {
33 update_tree(arr,tree,left_node,start,mid,idx,val);
34 }
35 else
36 {
37 update_tree(arr,tree,right_node,mid+1,end,idx,val);
38 }
39 tree[node]=tree[left_node]+tree[right_node];
40 }
41 }
42 int query_tree(int arr[],int tree[],int node,int start,int end,int L,int R) //区间求和
43 {
44 if(L>end||R<start) //出口
45 {
46 return 0;
47 }
48 else if(L<=start&&end<=R)
49 {
50 return tree[node];
51 }
52 else if(start==end) //此处的意思就是到了叶子节点了
53 {
54 return tree[node];
55 }
56 else
57 {
58 int mid=(start+end)/2;
59 int left_node=2*node+1;
60 int right_node=2*node+2;
61 int sum_left=query_tree(arr,tree,left_node,start,mid,L,R);
62 int sum_right=query_tree(arr,tree,right_node,mid+1,end,L,R);
63 return sum_left+sum_right;
64 }
65 }
66 int main()
67 {
68 int arr[]={1,3,5,7,9,11};
69 int size=6;
70 int tree[MAX_LEN]={0};
71 build_tree(arr,tree,0,0,size-1);
72 for(int i=0;i<15;i++)
73 {
74 cout<<"tree"<<"["<<i<<"] "<<"="<<tree[i]<<endl;
75 }
76 cout<<endl;
77 update_tree(arr,tree,0,0,size-1,4,6);
78 for(int i=0;i<15;i++)
79 {
80 cout<<"tree"<<"["<<i<<"] "<<"="<<tree[i]<<endl;
81 }
82 cout<<endl;
83 int s=query_tree(arr,tree,0,0,size-1,2,5);
84 cout<<s<<endl;
85 return 0;
86 }