關於樹狀陣列的一點通俗理解

2021-08-28 12:15:22 字數 1191 閱讀 5815

首先講一下樹狀陣列的作用吧,樹狀陣列主要應用於對資料的查詢、修改等維護操作,就比如有乙個陣列a,下標從0n-1,現在給你w次修改,q次查詢,修改的話是修改陣列中某乙個元素的值;查詢的話是查詢陣列中任意乙個區間的和,在資料規模很小的時候,無論是修改某點的值還是查詢某區間的和所需要的時間和空間幾乎忽略不計,但當資料規模非常大時,就會有一些不可避免的弊端,如查詢區間和時,需要把查詢區間的資料全部遍歷一遍,這時候修改的時間複雜度為o(1),查詢為o(n),這時候為了節省時間,提高演算法效率,就需要對演算法進行優化,如果採用字首和的方法這時修改的時間複雜度為o(n),查詢為o(1),總有以部分功能是非常耗時的,但樹狀陣列卻可以完美解決這個問題。

關於樹狀陣列的講解在網上有許多部落格介紹,但在查閱這些部落格時,個人感覺這些部落格講的有一點點太理論化,對於新手來說不是非常友好,比較適合那些有一定基礎的人看,於是就有了這篇部落格,算是我對樹狀陣列的個人理解。

對於樹狀陣列,個人感覺難以理解的地方就在於不明白lowbit(x)對於x的意義,lowbit函式對於樹狀陣列來說是非常重要的,甚至說是核心都不為過,樹狀陣列的資料結構形似一棵樹,對於樹來說連線的關鍵是節點,節點有根節點、子節點之分,而lowbit(x)表示的就是x所在根節點下擁有的全部子節點,如下圖

由以上兩圖可以看出,1節點所擁有的子節點為a1,1個子節點,2節點擁有的子節點為a1、a2,2個子節點,4節點擁有的子節點為a1、a2、a3、a4,4個子節點等等,往後可以看出明顯的規律。

這樣在進行查詢操作時,只需要把k節點下的所有節點累加即可,**例子如下:

int read(int k)//1~k的區間和

return sum;

}

在上面**裡,通過k-=k&-k來不斷跳轉根節點,  實現樹的遍歷      

修改操作,例子如下:

void add(int k,int num)

}

在修改操作裡,通過k+=k&-k操作來跳轉父節點,更新所有相關節點的狀態。

樹狀陣列一點心得

樹狀陣列的基本概念不說了,網上大佬們的講解部落格很多。先上一段我的模板 inline int lowbit int x inline void update int x,int val for int i x i舉兩個例子來加深一下對樹狀陣列的理解。可以知道維護的 tree 陣列 表示到第 i 項的...

關於malloc的一點理解

在函式中使用malloc,如果是大的記憶體分配,而且malloc與free的次數也不是特別頻繁,使用malloc與free是比較合適的,但是如果記憶體分配比較小,而且次數特別頻繁,那麼使用malloc與free就有些不太合適了。因為過多的malloc與free容易造成記憶體碎片,致使可使用的堆記憶體...

關於HTTPS的一點理解

通訊使用明文 不加密 內容可能會被竊聽。不驗證通訊方的身份,因此有可能遭遇偽裝。無法證明報文的完整性,所以有可能已經遭到篡改。https http 認證 加密 完整性保護 https是與ssl 安全套接層 組合使用的http協議 http secure 使用ssl之後,請求則變成先和ssl通訊,ss...