2011-10-02 28 views
7

爲什麼mergesort在排序列表時不考慮快速排序時考慮「走的路」? 我在網上看過的一個講座中聽到了這個消息,並在幾個網站上看到了它。爲什麼mergesort更適合鏈接列表?

+1

檢查出來 http://stackoverflow.com/questions/497794/quicksort-slower-than-mergesort –

回答

17

Quicksort效率的主要來源之一是locality of reference,其中計算機硬件經過優化,以便訪問彼此接近的內存位置往往比訪問散佈在內存中的內存位置更快。快速分區中的分區步驟通常具有優良的局部性,因爲它可以訪問前後附近的連續陣列元素。因此,快速排序往往比其他排序算法(如堆排序)執行得更好,即使它經常進行大致相同數量的比較和交換,因爲在排序情況下,排序更加分散。

此外,快速排序通常比其他排序算法快得多,因爲它就地操作,無需創建任何輔助數組來保存臨時值。與合併排序相比,這可能是一個巨大的優勢,因爲分配和釋放輔助數組所需的時間可能會很明顯。在原地進行操作也可以提高快速排序的位置。

使用鏈接列表時,這些優點都不一定適用。由於鏈接列表單元格通常分散在整個內存中,因此訪問相鄰鏈接列表單元格時沒有局部獎勵。因此,quicksort的巨大性能優勢之一就被吃光了。同樣,就地工作的好處不再適用,因爲合併排序的鏈表算法不需要任何額外的輔助存儲空間。

這就是說,quicksort在鏈表上仍然非常快。合併排序的速度通常會更快,因爲它更平均地將列表分成兩半,每次迭代執行合併的工作量少於執行分區的步驟。

希望這會有所幫助!

+0

在第三段的最後一行中,你寫道:「同樣,就地工作的好處不再適用,因爲合併排序的鏈表算法不需要任何額外的輔助存儲空間。」爲什麼它不需要輔助存儲空間? – Geek

+0

@Geek我可能應該說「合併排序的鏈表算法不需要** O(n)**輔助存儲空間。」標準的基於數組的合併算法要求您在合併過程中分配額外的存儲空間,因爲這些元素需要移動。在鏈接列表的合併排序中,可以通過重新鏈接它們來移動元素而不分配外部數組。 – templatetypedef

1

find()的成本比mergesort更有害於quicksort。

合併排序對數據執行更多「短程」操作,使其更適合鏈接列表,而快速排序可以更好地使用隨機訪問數據結構。

+0

你是什麼意思的find()? – templatetypedef

+0

在數據結構中尋找條目。對於一個有聯繫的演員,你總是前進/倒帶,就像演奏磁帶一樣。 –

+0

您不需要在鏈接列表大小寫中使用數組上使用的隨機訪問分區函數進行快速排序。您可以通過遍歷列表來分割鏈表,並將每個元素分配到三個列表中的一個 - 「少於」列表,「大於」列表和「等於列表」,然後在後兩個列表上遞歸。你說得對,標準分區很慢,但這並不會使鏈接列表快速排序變慢。 – templatetypedef