• 树状数组


    树状数组

    定义

    树状数组(Binary Indexed Tree(B.I.T), Fenwick Tree)是一个查询和修改复杂度都为log(n)的数据结构。主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值;经过简单修改可以在log(n)的复杂度下进行范围修改,但是这时只能查询其中一个元素的值(如果加入多个辅助数组则可以实现区间修改与区间查询)。

    作用:

    • 实现求数组前缀和
    • 实现批量更新
    • 区间和快速查询(实质是两个端点前缀和相减得到)

    下图为树状数组实现原理,红色箭头代表更新操作的执行顺序,绿色箭头代表查找操作的顺序

    lowbit(x)就是求x最后一个1所代表的值,例如lowbit(9) = lowbit(1001) = 1
    机器计算表达式为lowbit(x) = x & (-x),以12也就是1100为例:

    计算机组成原理:
    正数的原、反、补码都是其本身,负数的反码等于原码取反, 补码等于反码+1,计算都是通过补码进行
    
     x = 0 1100  (12)
    原、反、补码都是01100,最前面的0为符号位
    -x = 1 1100  (-12)
    原码  1 1100   
    反码  1 0011
    补码  1 0100
    
    x & ( - x ) = 01100 & 10100 = 00100
    即取到了最后一位的值 100
    
    let arr = [];
    function lowbit(x) {
        return x & (-x);
    }
    /* 给index索引的结点+value */
    function add(index, value) {
        while (index <= 16) {
            arr[index] = arr[index] == undefined ? value : (arr[index] + value);
            index += lowbit(index);
        }
    }
    /* 查询前缀和 */
    function query(index) {/* 查询前缀和,结束位置为index */
        let sum = 0;
        while (index > 0) {
            sum += arr[index] == undefined ? 0 : arr[index];
            console.log(index, arr[index])
            index -= lowbit(index);
        }
        return sum;
    }
    /* 查询x~y区间 */
    function getSum(x, y) {
        return query(y) - query(x - 1); 
    }
    
  • 相关阅读:
    Netty相关知识积累
    Java内存管理
    使用nginx-upload-module搭建文件上传服务器
    mysql 5.7自动安装脚本
    CDH5集群搭建
    Linux常用命令
    编译原理要点四
    编译原理要点三
    编译原理要点二:
    编译原理要点
  • 原文地址:https://www.cnblogs.com/aeipyuan/p/12990179.html
Copyright © 2020-2023  润新知