线段树

 1 #include <iostream>
 2 #define MAX_LEN 1000
 3 using namespace std;
 4 
 5 //arr代表需要查询的数组,tree代表根据查询数组建立的堆, start代表起始点, end代表终止点 
 6 void build_tree(int arr[], int tree[], int node, int start, int end){
 7     if(start == end){//探测到叶子节点,把数据存入叶子节点,然后返回 
 8         tree[node] = arr[start];
 9     }else{
10         int mid = (start + end) / 2; 
11         int left_node = 2 * node + 1;//左子节点
12         int right_node = 2 * node + 2;//右子节点
13         build_tree(arr, tree, left_node, start, mid);
14         build_tree(arr, tree, right_node, mid + 1, end);
15         tree[node] = tree[left_node] + tree[right_node]; //返回后将子节点的和更新到父节点 
16     }
17 }
18 //idx为待更新值的下标val是更新后的值 
19 void update_tree(int arr[], int tree[], int node, int start, int end, int idx, int val){
20     if(start == end){//到达叶节点 
21         arr[idx] = val;//将叶节点值更新 
22         tree[node] = val;
23     }else{
24         int mid = (start + end) / 2;
25         int left_node = node * 2 + 1;
26         int right_node = node * 2 + 2;
27         if(idx >= start && idx <= mid){
28             update_tree(arr, tree, left_node, start, mid, idx, val);
29         }else{
30             update_tree(arr, tree, right_node, mid + 1, end, idx, val);
31         }
32         tree[node] = tree[left_node] + tree[right_node];//将父节点更新 
33     }
34 } 
35 int query_tree(int arr[], int tree[], int node, int start, int end, int L, int R){
36     if(R < start || L > end){//不是连续区间 
37         return 0;
38     }else if(L <= start && end <= R){//树上存在区间在查询的区间范围内 
39         return tree[node];//将该区间的和返回 
40     }else if(start == end){//查到叶子节点 
41         return tree[node];
42     }else{//查询区间在树的俩个不同的区段中 
43         int mid = (start + end) / 2;
44         int left_node = 2 * node + 1;
45         int right_node = 2 * node + 2;
46         int sum_left = query_tree(arr, tree, left_node, start, mid, L, R);
47         int sum_right = query_tree(arr, tree, right_node, mid + 1, end, L, R);
48         return sum_left + sum_right;//返回该区段和 
49     }
50 }
51 int main(){
52     int arr[] = {1,3,5,7,9,11};
53     int size = 6;
54     int tree[MAX_LEN] = {0};
55     build_tree(arr, tree, 0, 0, size - 1);//将上述序列存入线段树 
56     int i;
57     for(i = 0; i < 15; i++){
58         printf("tree[%d] = %d\n", i, tree[i]);
59     }
60     printf("\n");
61     update_tree(arr, tree, 0, 0, size - 1, 4, 6);//将下标为4的位置更新,还需要更新整个树 
62     for(i = 0; i < 15; i++){
63         printf("tree[%d] = %d\n", i, tree[i]);
64     }
65     int s = query_tree(arr, tree, 0, 0, size - 1,2, 5);//查询所求和 
66     cout << s;
67     return 0;
68 } 

优秀博文:

https://www.cnblogs.com/AC-King/p/7789013.html

https://www.cnblogs.com/TenosDoIt/p/3453089.html

posted @ 2019-04-09 12:47  kakaluotedj  阅读(234)  评论(0编辑  收藏  举报