树状数组介绍
在学习一个算法之前一定要清楚它能干嘛,能解决什么样的问题,对你解题是否有帮助,然后才去学习它!
那么接下来看如下几个问题
什么是树状数组
顾名思义就是一个结构为树形结构的数组,于二叉树的结构类似但又不同,它是在二叉树的结构上删除了一些中间节点,来看两幅图就明白了.
1.这是二叉树的结构
2.这是树状数组的结构
不难发现,树状数组相比于二叉树删除了一些节点,但是为什么要删除呢?这就和树状数组的一些性质(lowbit)有关了,不懂没关系,继续往下看.
树状数组可以解决什么问题呢?
可以解决大部分区间上面的修改以及查询的问题,例如
1.单点修改,单点查询
2.区间修改,单点查询
3.区间查询,区间修改
换言之,线段树能解决的问题,树状数组大部分也可以,但是并不一定都能解决,因为线段树的扩展性比树状数组要强.
树状数组和线段树的区别在哪?
有人会问了既然线段树的问题能够用树状数组解决而且线段树还比树状数组扩展性强,那为什么不直接用线段树呢?问的很好,树状数组的作用就是为了简化线段树,举个例子:一个问题可以用线段树解决写代码半个小时,但是用树状数组只需要10分钟,那么你会选择哪一个算法呢?没错,基于某些简单的问题,我们没必要用到功能性强但实现复杂的线段树(杀鸡焉用宰牛刀).
树状数组的优缺点
优点:修改和查询操作复杂度于线段树一样都是logN,但是常数比线段树小,并且实现比线段树简单
缺点:扩展性弱,线段树能解决的问题,树状数组不一定能解决.
树状数组讲解
前置知识—lowbit(x)运算
如何计算一个非负整数n在二进制下的最低为1及其后面的0构成的数?
例如:44 = ( 101100 ) 2 44=(101100)_244=(101100) 2,最低为1和后面的0构成的数是( 100 ) 2 = 4 (100)_2=4(100) 2=4
所以l o w b i t ( 44 ) = l o w b i t ( ( 101100 ) 2 ) = ( 100 ) 2 = 4 lowbit(44)=lowbit((101100)_2)=(100)_2=4lowbit(44)=lowbit((101100)2)=(100)2 =4
那么lowbit运算时怎么实现的呢?
44的二进制=(101100),我们对44的二进制数取反+1,也即~44+1,得到-44
-44的二进制=(010100),然后我们把44和-44的二进制进行按位与运算,也即按位&得到,二进制000100,也就是十进制的4。所以lowbit(x) = x&(-x)
最后
本文对鲜果维他命大佬的文章多有借鉴。
原文链接如下: