Algorithms Part 1 — Week 2之Stacks筆記

Free online course presented by Robert Sedgewick and Kevin Wayne

這篇將會概括PPT 1.3的stack以及resizing arrays:

Stacks

對就是那個Stack,LIFO的資料結構。這門課的老師很強調把Client, implementation, 還有interface分開,因為有以下優點

  • Client不用知道實作細節,但可以完整使用

  • 可以實做出modular, reusable libraries

  • 效能上可以在需要的地方寫上optimized implementation

有點離題了,拉回來。個人覺得PPT裡寫得非常詳細,這裡就補充一些可能看不懂或是複雜的地方吧。

一開始PPT給的是StackOfStrings,存放string的stack,裡面有實作,請參考PPT。用Linked-list實作stack

看到這個PPT我才想起Java有inner class,很久以前有用過,但後來就沒必要也就沒寫過了。

Linked-list implementation

如圖,而inner class的access modifier,也就是那個private無所謂,反正都存取得到。

而這個Stack會用到的Memory大約是40N,見下圖

Stack memeory

注意實際String的內容都沒有算進來,只是算最少要多少,還加上了String的reference。

另外也可以用Array實作stack,code也在PPT裡面了。但目前需要傳入capacity,否則array最終會超出範圍。

Stack的隱憂與解法

  • Underflow: 如果在空的stack pop的話,拋出exception

  • Overflow: 用可變大小數組

  • Null items: 允許null item插入

  • Loitering: Garbage collector不知道可以回收,所以浪費了空間,解決方法參照PPT P.14

於是引出我們下一個主題

Resizing Arrays

如果每次超過array size就只增加到多出來的長度,那需要N²/2的時間才能插入從第一個到N個items,因為每次都要再copy。因此我們每次增加都直接增加兩倍,這樣就可以把時間壓到剩3N(不考慮新建一個array的時間),因為很少需要擴充。這個行為叫做amortize攤銷。

而如果太多空間的話,我們每次剩一半以下就直接砍掉一半空間就好了?

不對,這樣如果有case是在一半的前一個push又pop,push又pop,這樣反反覆覆那時間會很可觀,因為每次要增加兩倍空間,接著又要去掉一半空間,每次操作基本上要N次。

那該怎麼做?在剩25%的時候shrink就好,這樣不會跟擴充array衝突,也能解決那樣極端的例子。

Stack的performance以及memory如何

Stack performance table

Stack memory usage

這裡我不懂為何8N的時候是stack滿的時候,反而32N是只有25%滿…

教授說array來實作stack使用的空間比Linked-list還少

用resizing array還是Linked list實作stack

有好有壞,看怎麼選擇

Linked-list vs Resizing array


Algorithms Part 1 — Week 2之Stacks筆記
https://f88083.github.io/2023/10/08/algorithms-part-1-week-2之stacks筆記/
作者
Simon Lai
發布於
2023年10月8日
許可協議