Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 对二叉索引树概念的理解较少_Algorithm_Data Structures_Language Agnostic_Tree - Fatal编程技术网

Algorithm 对二叉索引树概念的理解较少

Algorithm 对二叉索引树概念的理解较少,algorithm,data-structures,language-agnostic,tree,Algorithm,Data Structures,Language Agnostic,Tree,我在互联网上读了2-3本(又名芬威克树)的教程,但我不明白它到底做了什么,以及BIT背后的想法是什么。 我读的教程是 ,由 请帮助我了解BIT二叉索引树是一种数据结构,允许通过前缀检索值。我对二叉索引树的理解是,它们或多或少类似于尝试。例如,假设您有三个数字1323、1697和1642。您可以将数字存储在树中: 1-3-2-3 -6-9-7 -4-2 其中每个节点代表一个10秒的位置。现在你可以查任何电话号码,就像你可以在电话簿上一个字母一个字母地查名字一样。这里,每个节点

我在互联网上读了2-3本(又名芬威克树)的教程,但我不明白它到底做了什么,以及
BIT
背后的想法是什么。 我读的教程是

  • ,由

请帮助我了解
BIT

二叉索引树是一种数据结构,允许通过前缀检索值。我对二叉索引树的理解是,它们或多或少类似于尝试。例如,假设您有三个数字1323、1697和1642。您可以将数字存储在树中:

1-3-2-3  
 -6-9-7  
   -4-2
其中每个节点代表一个10秒的位置。现在你可以查任何电话号码,就像你可以在电话簿上一个字母一个字母地查名字一样。这里,每个节点的长度为10秒,但您可以选择不同的基准,以使表示尽可能紧凑。例如,您可以使用基数8,在这种情况下,每个节点存储4位


此数据结构允许您轻松添加数字。例如,假设您要添加数字#1(1323)和#3(1642)。然后从表示每个数字的叶子开始,向上计算,再乘以基数的幂(这里是10):3+2,然后(2+4)*10,然后(6+3)*100,然后(1+1)*1000。

顶级编码器文章不太清楚。这是一个可以让你开始的好主意

位用于存储从整数到整数的密集映射
f[i]
,其中
i>=1
,您感兴趣的是检索映射域范围内的和,即对于任意
a
b
,求和{i=a..b}f[i]。如果您使用C语言编写代码,这将是:

sum = 0; for (i = a; i <= b; i++) sum += f[i];
其中
d
k
的值,除最低阶位外,所有位均设置为零。例如,如果
k=8
,则
d=8
。如果
k=14
,则
d=2
,以此类推

注意,没有显式树。该树符合逻辑,如教程图片所示。唯一的存储是数组
g

为什么这是个好主意?事实证明,要找到
sum_{i=a..b}f[i]
,您最多只需将
2个上限(log(b+a))
元素的
g
相加即可。这些元素可以通过分析
a
b
的二进制1位来确定。教程中显示了详细信息

最简单的例子是:如果您想要
sum_{i=1..p}f[i]
,那么构建一系列索引
p_1
p_2
p_n
其中
p_1=p
p_(i+i)
通过从
p_i
中移除最低阶1位而形成。因此,
n
p
二进制表示中的1少一个。现在只需计算

sum_{k = p_1, p_2 ... p_n} g[k]

如果你尝试一下,想一想这一点(双关语),你就会明白它为什么会起作用。

二元索引树也称为芬威克树,我认为二元索引树比芬威克树更不为人所知,所以当我们发现二元索引树时,我们发现的材料更少,但这正是我的感觉

简单地说,Fenwick树(也称为二叉索引树)是一种数据结构,它维护一系列元素,并且能够在O(logn)时间内计算任意范围的连续元素的累积和。更改任何单个元素的值也需要O(logn)时间。 该结构具有空间效率,因为它需要与n个元素的简单数组相同的存储量

可以在网上的不同地方找到一个实际的例子来说明上述情况,即


网络上还有更多的例子…

比特是一件非常奇妙的事情,理解它的关键是了解快速分段算法的工作原理

快速分段算法和数据结构的基本思想是“跳过”一些东西。想想一个整数数组a[1..n]。现在你需要另一个数组C[1..n],在C[i]中包含C[i],C[i-1]到C[k(i)](k是某种神奇的函数(O-O))

当你想得到[1..i]的和时,你可以写:

    int get_sum(int i) {
        if (i == 0)
            return 0;
        return get_sum(k(i)-1)+C[i];
    }
很容易理解耶?我们只使用C[i]=sum(a[k(i)…i])而不是遍历整个段。当我们想要更改某个元素时,我们使用一个名为“add(pos,i)”的数组表示在[pos]中添加i:


(k’(x)是一个函数,返回k(y)的最小y>=x这类问题不适合SO的问答形式。如果你没有理解已经阅读的教程,我很难向你解释。不过,我建议你编写一个程序来实现二叉索引树。编程不是一项旁观者运动,边做边学是一种很好的学习方式。正如你写代码,不停地问自己,不仅仅是代码在做什么,还有为什么。好吧,我试着用那个教程来编写代码,但是没有任何概念的感觉,编码变得枯燥,这就是为什么我发布这个问题。这不是一个好主意,编程时不知道该做什么。在BIT的情况下完全错误。这样的结构是抽象不喜欢UI开发,原型设计很有帮助。@FreakyCheeky您所指向的网站看起来很简单,提供的信息也足够多。您应该从描述它的哪一部分很难理解开始。在我看来,似乎没有投入足够的精力/时间来真正理解它。@mmgp我不知道grre,介绍没有很好地解释。细节解释得更好。你也应该试着找其他文章。(可能)在阅读了你的答案和topcoder博客多次之后,原版人理解了整个算法。但我的问题是,这棵树是如何工作的,从何而来,我想知道这个数据结构背后的基本思想。还有一个问题,开始构建树数组的复杂性是什么?在同一页上有一个问题关于卡片的问题(问题2)。请解释一下
    int get_sum(int i) {
        if (i == 0)
            return 0;
        return get_sum(k(i)-1)+C[i];
    }
    void add(int pos, int i) {
        if (pos <= n) {
            C[pos] += i;
            add(k'(pos), i);
        }
    }
    (110100)2 --BIT--> (100)2
    (111)2    --BIT--> (1)2
    (100000)2 --BIT--> (100000)2
    BIT(x) = x & ((~x) + 1)
    k(i) = i-BIT(i)+1
    k'(i) = i+BIT(i)