我的问题涉及二进制索引树(Fenwick树)中更新步骤背后的全部原因。这样,当在某个位置以某个增量更新数组时,更新将如下所示:
void updateBIT(int BITree[], int n, int index, int val)
{
// index in BITree[] is 1 more than the index in arr[]
index = index + 1;
// Traverse all ancestors and add 'val'
while (index <= n)
{
// Add 'val' to current node of BI Tree
BITree[index] += val;
// Update index to that of parent in update View
index += index & (-index);
}
我的问题是index += index & (-index);
部分。请注意,我理解index & (-index)
位,尤其是在查询树的上下文中。
我已经使用此索引更新规则手动尝试了几个示例,但是我无法找到添加index & (-index)
背后的逻辑以便转到下一个需要更新的节点。 / p>
从我起步到现在,BIT中的节点i
对数组[i - i & (-i) + 1, i]
范围内的原始值是“负责任的”,这意味着任何节点都将落入这种形式的范围。具体来说,据我所知,当要更新原始数组中的位置k
时,我们按照以下步骤操作(从概念上讲,不在实际代码中):
0
:更新BIT[k + 1]
(索引在索引行中移动了1
。
BIT数组)。虽然仍在迭代0
上,但我们更新了索引
看,所以我假设我们正在寻找下一个最小的
负责节点k
的时间间隔,因此我们需要找到
下一个索引i
,其中i - i & (-i) < k < i
。在以下位置找到该索引i
将当前索引增加k & (-k)
。其余的迭代以相同的方式发生,直到我们超出极限为止。我已经手工尝试了许多示例,但仍然不明白为什么添加i & (-i)
将我们带到正确的下一个节点。我在网络上找到的每个教程(包括视频)在这个问题上都是完全模糊的。
这里有几个有关BIT的相关问题,在仔细阅读之前,请不要将它们与我的合并。据我所知,这个特定的问题尚未得到解答。
答案 0 :(得分:0)
所以,让我尝试通过一个简单的例子来解释上述情况。
让我们来i = 12
。现在,我们更新BIT[12]
。现在,根据要更新的算法的下一步是i += i&(-i)
。
二进制数= 01100
中的12是什么。设置的最后一位是2
,值是2^2
= 4(如您所知
0th bit value is 2^0 = 1
1st bit value is 2^1 = 2
2nd bit value is 2^2 = 4.
以类似的方式处理其他位。
所以现在我们要更新的下一个索引是12 + 4 = 16
。即BIT[16]
。
现在这是关于系统的工作方式。让我尝试用简单的词来解释这种技术为何有效。
让我们说我需要更新index = 1
,假设MAX数组的值为8。那么我将更新1,2,4,8
的所有索引是什么。
现在,假设我需要更新index = 3
。因此,数组索引将更新3,4,8
。
因此,您将看到BIT[4]
到目前为止如何从数组索引1 to 4
中获得所有值的总和。
现在假设您需要获取前4个数字的总和,只需执行BIT[4]
,然后遍历索引4,0
。简而言之,您不会遍历1,2,3
。如我们所见,由于位操作,这些索引是如何被覆盖的。
希望这会有所帮助!