樹狀陣列總結

2021-08-29 04:01:04 字數 1582 閱讀 9942

第一次接觸樹狀陣列是大一時候還在企圖搞演算法競賽的時候,但那個時候也沒什麼心思花在上面,沒搞懂過,只是抄抄模板水水過。現在為了考研明年要考pat,開始刷pat題庫了而且碰到這種題目了,沒辦法了,只能學一下了。也不是很深入,但是我覺得用用是夠了。下面是介紹。

一.樹狀陣列要解決的問題:

有過演算法學習經驗的人應該都知道poj一道經典的區間求和題,是的樹狀陣列可以解決,區間的更新,區間的求和還有求字首和的問題,因為他的查詢和修改複雜度都是logn,效率很高。

二.樹狀陣列是什麼:

其實就是叫二叉索引樹,目的就是把線性結構的陣列變成樹狀結構。如下圖所示

其中最小面的圓圈表示乙個陣列,分別是123456,然後上面的圓圈表示和他相連的圓圈的和。我們可以看出,通過這些節點的加減,我們可以得出乙個陣列裡連續幾個數字的和。然後後面幾個數字的和都可以由這幾個數字的和相加。

我們把這些記錄一小段一小段區間的和存在乙個陣列裡面,命名為treearr,我們先這樣想,我們如何去理解他們完成一中提到的功能。

1.對於區間求和,我們僅需要確定起始位置和結束位置,比如i和j,我們可以得出和就是從第乙個到第j個元素的和減去從第乙個到第i-1個元素的和。那麼如何求第乙個元素開始到最後乙個元素的和呢,我們如何求treearr呢?

2.對於treearr的初始化,我們又該如何進行呢,要按什麼規律去做?

三.lowbit函式

**如下:

int lowbit(int x)
這個函式是幹嘛用的呢?學過c語言的應該都知道的&的意思是異或,這個函式的作用是返回乙個數用二進位制表示後,最後乙個1的位置,拿6舉例,用二進位制表示為

然後6&-6等於之後等於2.就是最後乙個1的位置。

四.樹狀陣列的區間和如何查詢?

我們可以把6=110拆成,110=100+10;100是多少?4,10是多少?2.然後去觀察上圖,正好是這樣。前面4個構成一組,後面2個構成一組。這也就是lowbit返回出來的位置拆開來。這裡需要去體會一下,那麼我們就找到了規律了。我們只需要從樹的最高處往下累加到最後一層非葉子節點即可,按照lowbit(goal)的間隔去累加即可,goal為你要查的目標。**如下:

int sum(int x, int *c) 

return res;

}

五.樹狀陣列的維護?光知道查詢肯定沒用的,我們需要維護這個樹狀陣列的。不然就沒有treearr,又怎麼會有查詢呢。

其實到這裡一般都有想法了,上面查詢是從上而下照下來,那麼這裡和就從下而上加上去就行了,我們可以知道上面的陣列各項並不都與乙個數的改變有關係,那麼我們只需要把和它相關的treearr修改了就行了。**如下;

void update(int x, int data, int *c,int size) 

}

這樣就實現了所有操作了。但是我們仍然需要知道這個不能做到的事情。比如動態的更新,還有只能用於求和的侷限性。

樹狀陣列總結

樹狀陣列的基本知識已經被各種大牛和菜鳥講到爛了,我就不多說了,下面給出基本操作的 假定原陣列為a 1.n 樹狀陣列b 1.n 考慮靈活性的需要,使用int a傳陣列。define lowbit x x x int sum int a,int x void update int a,int x,int...

樹狀陣列總結

樹狀陣列是對乙個陣列改變某個元素和求和比較實用的資料結構。兩中操作都是o logn 在解題過程中,我們有時需要維護乙個陣列的字首和s i a 1 a 2 a i 但是不難發現,如果我們修改了任意乙個a i s i s i 1 s n 都會發生變化。可以說,每次修改a i 後,調整字首和s在最壞情況下...

樹狀陣列總結

今天學習了一下樹狀陣列,做乙個簡單總結。樹狀陣列可分為兩種操作,1 修改單個點,統計區間和 一般為 向上修改 update1 向下統計 sum1 2 修改區間,統計單個點 一般為向下修改 update2 向上統計 sum2 主要模板如下 int c n int lowbit int x 用於確定區間...