如果知道堆棧大小良好的上限,使用了O一個數組(如另一個答案中概述的)可能是一個合理的事情。所有六個操作都是O(1),並且如果堆棧經常在最大尺寸附近運行,則每個元素的存儲量是最佳的。另一方面,如果您不知道堆棧大小的上限,或者堆棧大小通常與上限相比較小,則使用雙向鏈表,如下所述。另一方面,如果您不知道堆棧大小的上限,或堆棧大小通常比上限小,則使用雙向鏈表,如下所述。同樣,所有六個操作都是O(1)。如果堆棧的運行接近最小大小,則每個元素的存儲空間是最佳的 - 您將不會有大量閒置的陣列空間。請注意,以下顯示爲「新」和「空閒」的內存分配可以由malloc()和free()調用組成,也可以是通過使用可用節點池限制開銷的一些常用方法。
讓H指向列表頭,T指向尾部,M指向中間。 (M可以在每次更改時保持O(1),如下所示。)初始化列表大小s = 0和中間計數m = 0。
爲您的操作1-6:
無效推送(E E):
結交新節點X與E值; ++ S;如果(s == 1)設置H = T = M = X並設置鏈接,否則{附加X在H;設H = X; (s/2 + 1),則{++ m和設定M = M.next}}。
void pop(E e):if s < 1 return null or error;如果(s == 0)H = T = M = null,否則如果m>(s/2),則返回H,H = H.next,取消鏈接並釋放H.prev, +1),然後{--m並設置M = M.prev}}。
E peekMidElement(); [大小()/ 2)+1]:如果M,還給我否則返回null
ËpeekHighestElement():如果H,返回他(或Te)否則返回null
ËpeekLowestElement()?如果T,返回特否則返回null
INT尺寸()(或他):返回小號
我不知道該堆棧的到底是 「高」;你看到它正在成長,還是在成長?無論如何,只要你喜歡修復操作,並更改爲像peekHeadElement或peekFirstElement等名稱
所有方法都要經常調用。而且它的時間效率也很重要。 –
只有時間效率?以數組的形式實現它。 – Malvolio