【数据结构】树状数组

来源:互联网 发布:百度关键词挖掘软件 编辑:程序博客网 时间:2024/06/05 06:11
     什么是树状数组?顾名思义,就是一个数组,但是却可以看成是一棵树,它以树的方式来存储数据。
    如果我们给定一个数组,要求里面全部数据的和,一般来说会想到累加,但其时间复杂度是o(n),有的情况下,当询问多次时不能满足我们的需求。也有的人说用前缀和不就好了,但如果遇上要某个数加上一个数据呢?这样显然是不行的,我们就要用到树状数组了。
    那我们一定要用这张图了:
    【数据结构】树状数组 - 李kuandui - 神殇KD灬度阡陌
    那么观察存储方式,我们很难发现什么,但如果将其转化成二进制就简单多了!如:6=110,它最低一位是2,证明在a[6]中存储的是第5、6个数据之和,即从n开始往前lowbit(n)个数据和(包括第n个)。
    lowbit可以这样写:n=n&(-n);
    原理是什么?我不想说......
    -n即是n的按位取反再加一,这个不用说吧......

    知道了如何存储,我们就可以针对这个写出【某个位置的数加上一个数】和【求1~x的和】这两种关于树状数组的函数。代码如下:

【某个位置加上一个数】

void change(int x,int add)
{
while(x<=n)
{
a[x]+=add;
x+=(x&(-x));
}
}


【求1~x的和】

int sum(int x)
{
int s=0;
while(x>0)
{
s+=a[x];
x-=(x&(-x));
}
return s;
}


测试程序:

#include<iostream>
using namespace std;

int a[100],k,n;

int sum(int x)
{
int s=0;
while(x>0)
{
s+=a[x];
x-=(x&(-x));
}
return s;
}

void change(int x,int add)
{
while(x<=n)
{
a[x]+=add;
x+=(x&(-x));
}
}

int main()
{
cin>>n;
for(int i=1;i<=n;++i)
{
cin>>k;
change(i,k);
}
for(int i=1;i<=n;++i)
cout<<a[i]<<" ";
cout<<endl<<sum(n)<<endl;
}


以上就是关于树状数组的一些初步介绍。

虽然学了一种新的数据结构,但很可惜我们还没有遇到练手的题目,所以也不知道成果如何啊......

0 0
原创粉丝点击