如果有一串陣列,現在要把其中一段區間的所有數加起來,該怎麼辦?如果修改了其中的某個值之後再把它們加起來,又該怎麼辦?
直接加起來。這樣修改值所需時間是o(1),但是求和需要o(n),如果陣列一大,就有點慢了。
做乙個字首陣列,陣列裡第n個值就是原來陣列前n個數的和。經過預處理後,求和所需時間是o(1),但修改值後再求和所需時間就變成了o(n),我覺得這和第一種方法一樣雞肋,還更複雜了。
線段樹,也就是我今天學的東西,求和與修改值所需時間之間做了平衡。建樹需要o(n),使用時為o(logn)。
st表,沒學。
求最值的思想是一樣的,反正線段樹挺好。
假設陣列長度為n,將陣列轉換成一棵樹,樹的根節點所儲存的樹就是第0到第n-1個元素的和,其左右枝分別是第0到第(0+n-1)/2個元素的和與第1+(0+n-1)/2到第n個元素的和,以此類推,最後一定會算成兩片葉子(兩個元素)的和。
之後求區間和,就一定能分成一或兩個樹中元素的和,只需要找到這兩個元素即可。而修改值也只需要找到相對應的那一條枝幹即可。
我是看b站up主某月點燈籠學的線段樹,碼完之後改正美化也是照著來的,所以可以說**是完全一樣的。
#include
#include
#include
//將正常的陣列轉為一棵樹
void
build_tree
(int array,
int tree,
int root,
int op,
int ed)
}//修改樹葉之後,整條樹枝都要修改
void
re_tree
(int tree,
int root)
void
change_tree
(int array,
int tree,
int root,
int op,
int ed,
int leaf,
int num)
else
//查詢樹上對應的葉子
}//區間的樹葉求和
intsum_tree
(int array,
int tree,
int root,
int op,
int ed,
int l,
int r)
}int
main()
真的很想放棄,碼**著實沒有玩膠快樂。但是碼完之後寫部落格竟然讓我有了點成就感orz… 資料結構學習 鏈式棧的C語言實現
幾個概念 計算機中的儲存資料結構主要分為連續儲存結構和不連續儲存結構,其中連續儲存結構也稱為線性表,不連續儲存結構也稱為鏈式表。鏈式結構簡單的說就是不連續記憶體的陣列。棧作為一種資料結構,是一種只能在一端進行插入和刪除操作的特殊線性表。它按照先進後出的原則儲存資料,先進入的資料被壓入棧底,最後的資料...
資料結構學習 鏈式佇列的C語言實現
佇列是一種特殊的線性表,特殊之處在於它只允許在表的前端 front 進行刪除操作,而在表的後端 rear 進行插入操作,和棧一樣,佇列是一種操作受限制的線性表。進行插入操作的端稱為隊尾,進行刪除操作的端稱為隊頭。佇列中沒有元素時,稱為空佇列。佇列的資料元素又稱為佇列元素。在佇列中插入乙個佇列元素稱為...
資料結構學習 shell排序的C語言實現
shell排序 這個排序的命名是來自發明者的名字,和排序的方法沒有字面上的聯絡。所以不要因為名字而感覺很難。在k r的c程式語言中書中只用了幾行 很簡潔的實現了這個排序演算法。那就來看看這個排序是如何實現的。原理 我們將所要排序的序列 大小為n 劃分成組,組的數量一般是可以用這個序列的大小的一半來定...