問題語句丟失一個比較功能,所以我會限定比較(LISTA,數組listB)至LISTA的第一節點與數組listB的第一節點進行比較和用於=返回-1爲<,0,1對於更大或合併排序所需的全部數據,對於< =和0代表1。
另外還缺少一個返回值,表示在執行pa或pb時列表爲空。如果源列表不爲空,則定義pa或pb以返回1;如果源列表爲空(不需要複製節點),則返回0。
不清楚目標是否是最小的指令數量是指源代碼中的指令數量或排序過程中執行的指令數量。
-
最小的代碼將旋轉基於list2中的指令數目與list1的比較在適當的位置插入節點分成list2中。以pb開始,並將list2大小設置爲1.然後執行rb或rrb以將list2旋轉到下一個pb應該完成的位置。該代碼將跟蹤list2「偏移」到最小節點,以避免無限循環旋轉list2。複雜性是O(n^2)。
-
我在想最快的排序,也許執行的指令數最少是自下而上的合併排序。
在旋轉列表時使用它們(如循環緩衝區/列表)進行自底向上合併排序。使用序列|將list1複製到list2以生成節點計數count = 0 | while(pb){rb | count + = 1}。
使用計數,使用{pa,rr},n/2次將每個其他節點從list2移動到list1。始終跟蹤每個列表上的實際節點數量,以便知道何時到達列表的邏輯末尾。還要跟蹤每個列表的運行計數器,以瞭解運行的邏輯結束時間。此時,您有兩個列表,其中偶數節點位於list1上,奇數節點位於list2上。
運行大小從1開始,在每次通過時加倍。對於運行大小爲1的第一遍,將具有奇數節點的偶數節點合併,創建大小爲2的排序運行,交替地將排序的節點對附加到列表1和列表2。例如,如果追加到list1和list1節點< = list2節點,請使用{ra,run1count - = 1},否則使用{pa,ra,run2count - = 1}。到達運行結束時,將剩餘運行的剩餘部分追加到列表的末尾。在下一個過程中,合併來自列表的2個節點的已排序運行,交替地將已排序的4個節點運行追加到每個列表。繼續運行8,16 ...,直到所有節點都在一個列表中。
因此,這是一個通過計算節點,一次通過拆分偶數和奇數節點,並且ceil(log2(n))通過進行合併排序。鏈表操作的開銷很小(rotate會移除並附加一個節點),所以整體合併應該相當快。
可以通過while(pb){count + = 1}減少計數過程中指令的數量,這會將list1複製到list2中。然後將list2吐在list1中也會使用rrr來解決它們。
複雜性是O(n log(n))。
您可以使用這些操作進行相當高效的合併排序。 –
所以我應該把列表1的一半放在列表2中,然後同時對這兩個列表進行排序併合並它們? – Henry
我認爲某種快速排序或合併排序是最好的選擇。雖然存儲未使用的節點會有點棘手。 –