树状数组 Binary Indexed Trees

树状数组,英文名称是Binary Indexed Trees,又叫二分索引树。它是由二分索引方式构建的数组。由于其索引方式的特点,该数组中蕴含了一个树,树的每个结点都是是由数组元素构成,每个结点都表示了数组部分元素值的和。把数组和树联系起来,以数组的物理存储方式来表达树的逻辑架构,这和堆类似。


树状数组的构建方法:

假设原先的普通数组是这样的A[0],A[1],A[2]...A[n-1],那么我们这样构建树状数组C,

C[i] = A[i – i&(-i) + 1] + … + A[i] ,所累积的数组元素是从i出发向左的i&(-i)个数, i&(-i) = i&(i^(i-1)) 。

 i&(-i) 的直观效果是, 将一个数对应的二进制位仅保留最右边的1,其余为全置为0。

对于奇数i,i&(-i)=1,也就是树状数组的奇数项C[i]都是原数组对应项本身。

对于偶数i,如果它是2的幂数,则C[i]就是前i项和;如果不是2的幂数,C[i]就是某前些项的和。


于是,树状数组构建完成后就是这样:



树状数组的操作:

1、数组元素的访问

普通数组的元素访问时间复杂度是O(1),树状数组的元素访问时间复杂度是O(logn)

访问奇数项元素时,就是树状数组对应项本身。

访问偶数项元素时,则需要减去树状数组对应项的孩子。

2、数组元素的更新

普通数组的元素更新时间复杂度是O(1),树状数组的元素更新时间复杂度是O(logn)

更新奇数项元素时,直接更新对应项即可。

更新偶数项元素时,则需要把其对应项的父辈结点都更新。

3、求数组的前n项和

普通数组的序列求和时间复杂度是O(n),树状数组的序列求和时间复杂度是O(logn)。

int sum(int end) //求数组前end项和:找树的各个孩子
{
   int sum = 0;
   while(end > 0)
  {
     sum += in[end];
     end -= lowbit(end);
  }
  return sum;
}

void plus(int pos, int num) //增加某一个元素的大小:上行找树的祖先
{
   while(pos <= n)
  {
     in[pos] += num;
     pos += lowbit(pos);
  }
}

int lowbit(int t)
{
    return t & ( t ^ ( t - 1 ) );
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值