簡體   English   中英

如何在合並排序和插入排序之間進行選擇?

[英]How can I choose between merge-sort and insertion sort?

我需要實現最快的排序算法來對使用stdin創建的鏈表進行排序。

我知道合並排序的時間復雜度是O(n logn),插入排序的時間復雜度是O(n ^ 2)(是鏈接列表中元素的數量n)。

但是列表是由標准輸入創建的,因此,在未排序的列表上使用merge-sort還是更有效,還是通過插入排序來創建列表,這意味着對輸入進行排序,效率更高?

結構如下:

#define SIZE 50

struct node {
   int num;
   char name[SIZE];
   struct node* next;
};

這些是排序標准:

1. Sorted alphabetically by "name".
2. When the name is the same it's sorted by "num" (from higher to lower).

實際上,插入排序是一種在線算法,而合並排序是一種離線算法。 然而:

並非每個離線算法都有一個有效的在線對應方法。

在這里也是如此。

當數據已經部分排序時,您應該更喜歡插入排序而不是合並排序,因為前者是自適應算法。

注意:對於小尺寸輸入,插入排序也是首選。

通過使用比列表或向量更復雜的存儲(例如堆(請參閱堆排序)或集合或映射,二元樹類型或哈希映射類型,每個元素的插入成本為Ologn),可以提高插入排序的成本。 [當您不與主頁沖突時,Hashmap的成本為零,但如果可以生成完整的輔助/第三/等哈希值,則哈希表實際上是一棵壓縮的樹。 如果您的輔助系統是線性的,那么希望您的主哈希值是好的。]

傳統上,heapsort是受青睞的,因為它使用向量存儲,但是要順序登錄log,因此總體上使用Onlogn。 當然,您需要再次付費以按排序順序提取每個元素,因此總體來說它是2xOnlogn,仍然分類為Onlogn。

出於完整性考慮:由於對插入點的搜索是線性的,因此排序后的鏈接列表會受到影響。 排序的向量會受到影響,因為盡管很容易找到插入點,但騰出空間涉及每次(平均)復制一半的向量內容。

最多包含100個條目,這無關緊要。 插入排序或合並排序將花費不到20微秒的時間來排序100個節點的列表。 在我的系統(Intel 3770K,Windows 7 Pro 64位)上,使用鏈表的自底向上合並排序,甚至一百萬個節點只需要大約0.3秒即可在Java中進行排序,而對於C / C ++,則大約需要2 / 3rd。

對於大型列表,如果有足夠的內存,將鏈表復制到數組,合並對數組進行排序並創建新鏈表的速度最快。 數組排序要快得多,因為元素被移入了對緩存友好的組中,而鏈表排序則更改了鏈接而不是移動了節點,如果節點隨機分散,則對緩存不友好(最壞的情況是,每個訪問的節點都丟失緩存) )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM