数据结构篇六:Fenwick Tree (Binary Indexed Tree)

这是一位 google 工程师分享的8小时的数据结构的视频,我的笔记


Fenwick Tree (Binary Indexed Tree)

树状数组

Motivation

2021-11-30-14-14-04.png
  • 计算数组里任意连续片段的和,最直观的方案当然是累加:线性时间O(n)
  • 但是如果你有一个记录了每个节点到当前位置时的累加和的数组(prefix sum),立刻变成了常量时间
  • 问题是更新数据变成了线性时间(后续所有的求和都要改一遍)
    • great for static arrays

所以引入了:
Fenwick Tree is an efficient data structure for performing range/point queries/updates.(即在上面的动机上,还考虑了update的效率)

前面的例子在update时效率不高,所以Fenwick Tree用了一种聪明的方式,不是累加所有的值,而是分段累加,具体实现看下图:


2021-11-30-22-05-59.png
  • 把索引值用二进制表示
  • LSB的解释看图,实际应用上,就是看从低位到高位第一个1的右边有几个0,假设为n
  • 那么该cell上存的值就是前2^n个cell的值的和

图中例子是索引10,不直观,我们换成12, 二进制是1100, 最右边有2个零,那么它保存它2^2=4个位置的和。
也就是说,如果你要求和,如果用了cell 12位置的值的话,至少可以省掉3次累加。

当然,它还有更牛逼的特性,结合range query一起来看吧:


2021-11-30-22-19-28.png

蓝线表示的是当然位置上累加了前几个位置的值,已经很有规律了

假如计算前11个值的和,过程是:

  1. 11的索引是1011,右边没有0,所以当前的和为A[11]
  2. 根据2^0来移位,来到10。
    • 右边一个0,所以它管2^1个presum,目前A[11] + A[10]
    • 下一个索引自然要减2了,来到8
  3. 8是1000,3个零,所以它存了2^3=8个值的和,那就是全部了

所以:sum = A[11] + A[10] + A[8]

  • 心算sum(0,7)巩固一下
  • 用sum(11,15)演示子区间,其实就是多减1次,至于是减到10还是减到11,看描述,比如这里11是要参与计算的,那就是把前10个减掉就行了。

上面演示的都是worst的情况,即首位为1,除了这种情况,别的位都至少存了前2^n个元素的值(比如16,直接得到16个元素的和)

这里都没讲你是怎么做这个tree的,而是怎么使用它。先弄清楚使用场景再谈构建。

Point Update

复习一下LSB,虽然可以直接数最右边的零的个数,但数学其实是:

  • 13 = 1101 (2^3 + 2^2 + 2^0 \Rightarrow 10^3 + 10^2 + 10^0)
  • 减去最右边的1和0 => 1100 (2^3+2^2=12) 所以下一个数是12
  • 减去最右边的1和0 => 1000 就是8了
  • 再减就是0了
    而按2^n来计算个数的话就是这样的:
  • 13 = 1101, 没有0,就是移1位,变成12
  • 12 = 1100, 2个0, 就是移4位,变成8
  • 8 = 1000, 3个0, 移8位,变成0

现在来讲update,前面知道,update会级联影响到所以把该cell考虑进去的节点,因此,它需要反着往上找(极端情况当然是找到最后一个元素,通常这个元素就是整个数组的值,所以任何元素的更改,肯定都会影响到它)

前面找下一个节点用的是减法,现在就要用加法了,比如我更新了cell 9, 用以上两种任意一种方法来计算:

  • 9 = 2^3 + 1 \Rightarrow 10^3 + 1 = 1001, +1 = 1010 = 10
  • 1010 + 10 = 1100 = 12
  • 1100 + 100 = 10000 = 16 到顶了,
    所以需要把9, 10, 12, 16分别应用这个point的更新,也就是说只有这几个cell把9计算进去了。
2021-11-30-23-03-33.png

当然,可以看一下左边的示意图,更直观

function add(i, x): 
    while i < N:
        tree[i] = tree[i] + x 
        i = i + LSB(i)

代码非常简单,就是不断通过LSB找下一个位置去更新就行了。

Construction

现在来讲构建

function construct(values): N := length(values)
    # Clone the values array since we’re # doing in place operations
    tree = deepCopy(values)
    for i = 1,2,3, ... N:
        j := i + LSB(i)
        if j < N:
            tree[j] = tree[j] + tree[i]
    return tree

几乎就一句话,就是把元素按原数据摆好(即不加别的节点)后,每次找到当前元素影响的上一级(不再向上冒泡)

  • 比如1,把1算进去的有2,虽然上面还有4, 8, 16,但只把1更新到2
  • 到2的上一级是4 (2 + lsb(2) = 4), 把节点2的现值(已经加了节点1)加到4去
  • 所以核心算法始终只有两个变量,i,j代表最近的包含关系

一些算法换成位运算

  • lsb(i): i & -i
  • i -= lsb(i) => i &= ~lsb(i)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容