zoukankan      html  css  js  c++  java
  • 线段树

     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
    ", i, tree[i]);
    59     }
    60     printf("
    ");
    61     update_tree(arr, tree, 0, 0, size - 1, 4, 6);//将下标为4的位置更新,还需要更新整个树 
    62     for(i = 0; i < 15; i++){
    63         printf("tree[%d] = %d
    ", 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

  • 相关阅读:
    第一章 Shell基础知识
    keepalived与LVS实现高可用
    集群简介
    基于NFS v4版本搭建NFS服务器
    LDAP安装步骤
    Nginx配置阿里云https服务
    zabbix基础
    Apache、Nginx和Tomcat之虚拟主机配置
    标准盒模型和怪异盒模型的区别
    js中数组扁平化处理
  • 原文地址:https://www.cnblogs.com/AGoodDay/p/10676201.html
Copyright © 2011-2022 走看看