如果使用數組實現,我可以看到使用兩個堆棧的優點,因爲使用數組比堆棧更容易實現堆棧。 但是,如果使用鏈表,優勢是什麼? 將棧彈出到隊列中的行爲增加了鏈接列表和數組實現的開銷。爲什麼使用兩個堆棧來創建一個隊列?
回答
這是實現在函數式編程語言隊列單純的功能性的常用方法(不可變的,但在共享結構)列表(例如Clojure中,哈斯克爾,二郎...):
- 用一雙名單代表第一個列表中的元素處於FIFO順序並且第二個列表中的LIFO順序的隊列
- 通過預先考慮到第二個列表排隊到隊列
- 通過取出隊列中的第一個元素列表
- 如果第一個列表爲空:反轉第二列表,並與它代替第一列表中,並用一個空列表
更換第二列表
(所有的操作除了任何可能的返回值返回新的隊列對象)關鍵是將一個元素添加到(從)一個純函數列表的前面是O(1),而反向操作是O(n)在所有出列處被分攤,所以它接近於O( 1),從而爲您提供一個具有不可變數據結構的隊列實現。
第二步,我相信最後一個單詞應該是'list'而不是'queue',使它像'通過預先考慮第二個列表入隊到隊列中。] – 2014-05-27 09:41:43
謝謝@LihangLi,修正了! – liwp 2014-05-27 09:50:12
這是一個很好的學習經驗,但不是一個實際的。
您可以使用兩個不可變的堆棧來創建一個不可變的隊列。
但是,如果你只是想要一個可變隊列,使用兩個棧是一個很好的方式,使它比使用鏈表更慢和更復雜。
此方法可用於使用兩個原子單鏈表基於堆棧構建lock-free隊列,如由Win32提供的:Interlocked Singly Linked Lists。 該算法可能如liwp's answer中所述,儘管重新打包步驟(第4項)可以進行一些優化。
無鎖數據結構和算法是一個非常令人興奮的(對我們一些人)編程領域,但它們必須非常小心地使用。在一般情況下,基於鎖的算法效率更高。
在一個多寫入器的單個閱讀器的情況下,很容易以高效的無鎖方式處理「入隊」操作,同樣對於出列(無需鎖定寫入者,並假設一個讀取器)如果一個人通過收件箱中的「全部彈出」操作(基本上是一個'Interlocked.Exchange')開始出列,如果可能有多個讀者,最好讓他們使用鎖定在彼此之間進行仲裁(他們的鎖定會'不會影響作家) – supercat 2012-09-25 22:09:01
這是我來這裏尋找的解釋,有一個好的先生。 – 2017-05-01 14:30:51
- 1. 在兩個堆棧隊列中創建一個toString
- 2. 使用兩個堆棧的隊列
- 3. 使用堆棧兩個隊列
- 4. 創建一個通用堆棧陣列
- 5. 堆棧和隊列,爲什麼?
- 6. 使用2個隊列實現堆棧
- 7. 嘗試使用堆棧創建隊列。爲什麼我得到一個無效的int轉換錯誤?
- 8. 什麼創建堆棧?
- 9. 爲什麼我們在Java中使用堆棧和隊列?
- 10. 使用C中的兩個堆棧實現隊列
- 11. 使用兩個堆棧實現隊列奇怪的錯誤
- 12. 使用隊列堆棧
- 13. C++堆棧/堆棧。爲什麼只有一個新操作員?
- 14. 隊列+堆棧C++
- 15. iOS4創建兩個UIActionSheets,3.1.3創建一個?爲什麼?
- 16. Qt:創建一個圖像的堆棧
- 17. C#:創建一個PictureBox的堆棧
- 18. 爲什麼使用cons創建一對兩個列表會產生一個列表和兩個元素?
- 19. 堆棧和隊列用java
- 20. 如何創建一個可以存儲隊列或堆棧的變量?
- 21. 實現了一個鏈表。需要幫助建立一個堆棧和隊列
- 22. 爲什麼這個具有兩個堆棧的隊列的實現不可變且線程安全?
- 23. 堆棧兩個UITableViews
- 24. 爲什麼要實現堆棧和隊列java
- 25. 使用2堆棧實現隊列
- 26. 堆棧和隊列的使用情況?
- 27. 堆棧溢出使用消息隊列
- 28. 爲調用堆棧創建最後一個變量
- 29. 堆棧兩列
- 30. 我想實現一個隊列,將反轉堆棧和打印堆棧FIFO?
誰使用兩個堆棧來創建隊列?我不太瞭解情況(對不起( – helios 2010-01-12 15:42:22