树状数组

树状数组(Binary Indexed Tree)是一种可以同时快速得到数组的前缀和和快速更新数组的数据结构。

树状数组有两个操作:

1  void update(int i, int delta):更新数组中下标为i的元素的值,将其值加delta

2  int prefixSum(int i):计算数组到下标为i的元素的前缀和

通常对于求长度为n的数组的前缀和的任务,我们可以将数组的前缀和提前计算出来保存到一个新的数组,此时求前缀和只有O(1)的时间复杂度,但是此时对数组中元素进行更新操作有O(n)的时间复杂度,如果数组元素需要频繁更新,则这种方法就会很慢。而使用树状数组这种数据结构可以使得计算前缀和与更新数组元素这两个操作的时间复杂度都为O(log n)。

时间复杂度:更新和求前缀和操作都是O(\log n)

空间复杂度O(n)

线段树与树状数组非常相似,都是在长度为n的数组中,以O(log n)的时间复杂度更新数组元素,以O(log n)的时间复杂度得到区间和/前缀和。

java代码实现

/**
 * index    prefixSum
 * (1) 1    1
 * (2) 10   2
 * (3) 11   3+2
 * (4) 100  4
 * (5) 101  5+4
 * (6) 110  6+4
 * (7) 111  7+6+4
 * (8) 1000 8
 * (9) 1001 9+8
 * (10)1010 10+8
 * (11)1011 11+10+8
 * (12)1100 12+8
 * (13)1101 13+12+8
 * (14)1110 14+12+8
 * (15)1111 15+14+12+8
 */
public class BinaryIndexedTree {
    private int[] a;
    private int[] tree;

    public BinaryIndexedTree(int size) {
        a = new int[size];
        tree = new int[size + 1];
    }

    public BinaryIndexedTree(int[] a) {
        this.a = a;
        tree = new int[a.length + 1];
        System.arraycopy(a, 0, tree, 1, a.length);
        for (int i = 1; i < tree.length; i++) {
            int j = i + (i & -i);
            if (j < tree.length) {
                tree[j] += tree[i];
            }
        }
    }

    public void update(int i, int delta) {
        a[i++] += delta;
        while (i < tree.length) {
            tree[i] += delta;
            i = i + (i & -i);
        }
    }

    public int prefixSum(int i) {
        i += 1;
        int sum = 0;
        while (i > 0) {
            sum += tree[i];
            i = i - (i & -i);
        }
        return sum;
    }
}

源代码地址https://github.com/SSSxCCC/Algorithm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SSSxCCC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值