推荐一篇很好的博客:http://www.cppblog.com/menjitianya/archive/2015/11/02/212171.html
一、树状数组的定义
基本定义:树状数组是利用二分的思想使得查询和修改的复杂度都为 log(n) 的数据结构,树状数组是通过前缀和思想,用来完成单点更新和区间查询的数据结构。
如上图,不难看出树状数组是一个不断地二分的过程。
如上图,其中A为普通数组,C为树状数组(C在物理空间上和A一样都是连续存储的)。树状数组的第4个元素C4的父结点为C8 (4的二进制表示为"100",所以k=2,那么4 + 2^2 = 8,下面会具体讲解树状数组节点的含义),C6和C7同理。C2和C3的父结点为C4,同样也是可以用上面的关系得出的,那么从定义出发,奇数下标一定是叶子结点。
谈到树状数组就很有必要谈一下线段树,下图就是一个线段树:
于是删除了线段树的所有右儿子,发现就形成了树状数组。与线段树相比,所用空间更小,速度更快,而且编程的复杂难度也大大减小。但是这里有一个前提条件,也是树状数组的缺陷:节点的数据必须是可加减,而且要满足a + b = c,c - a = b,比如集合运算,是不能通过父节点和左子节点 来计算右子节点的。
和ST相比,树状数组可以动态更新数据。