如果有人問你哪種排序演算法最奇怪,可能你會先在氣泡排序、選擇排序、快速排序等常見排序演算法中「搜尋」了。
有人在 Quora 上也發帖問了這個問題。於是乎,各種腦洞大開的奇特演算法就被列出來了。它們可能存在效能問題或無法實現,但是不可否認其創造性。
睡眠排序(Nipun Ramakrishnan 的回答)
這個搞笑演算法流傳於 4chan 的 /prog/ 板塊。無從查證具體出自哪位程式設計師,虛擬碼如下
1 2 3 4 5 6 7 8 9 |
procedure printNumber(n) sleep n seconds print n end for arg in args run printNumber(arg) in background end wait for all processes to finish |
演算法執行如下: 對於陣列中每個元素 x,開啟一個新程式:
- 休眠 x 秒
- 列印 x 所有元素同時開始計時。 只適用於非負數字。
Bogo 排序/猴子排序 (Ryan Turner的回答)
Bogo 排序/猴子排序,名字很奇怪。它是愚蠢排序中的一員。
主要來說,演算法就是你把元素隨機排列。
如果沒有排好序,再次把元素隨機排列。
如果還沒有排好序,你懂的。下面是個例子:
1 2 3 4 |
4, 7, 9, 6, 5, 5, 2, 1 (未排序) 2, 5, 4, 7, 5, 9, 6, 1 (隨機排列) 1, 4, 5, 6, 9, 7, 5, 2 (再次隨機排列) 1, 2, 4, 5, 5, 6, 7, 9 (天吶,真幸運) |
你不停地隨機排序,直到得到一個有序陣列。
毫無疑問這是最低效的排序演算法之一,除非你非常非常幸運。它時間複雜度是令人窒息的 O(n!),而且隨著元素數量增加,很有 O(∞) 的趨勢。
量子 Bogo 排序(Tyler Schroeder 的回答)
我是量子 Bogo 排序的粉絲:
- 隨機排列陣列中元素。
- 如果陣列沒有排好序,摧毀當前宇宙(這一步就拜託你了)
- 存活的宇宙將會有排好序的陣列。 時間複雜度僅僅 O(n) 注意:這種演算法依賴於量子力學的平行宇宙理論的可靠性。如果量子力學的平行宇宙理論不準確,這個演算法時間複雜度達不到 O(n)
列印店頁碼排序 (Yi Wang的回答)
這並不是我發明的,我從別處看到的。
一個學生去列印店列印材料。他需要兩份,但並沒有直接列印兩份,而是將每一頁列印了兩次,像下面這樣:
需要的頁碼順序: 1 2 3 4 … N; 1 2 3 4 … N
手上的頁碼順序: 1 1 2 2 3 3 4 4 …. N N
他開始對列印材料排序,取一頁放在左邊,然後取一頁放在右邊。列印店老闆看不下去了,直接把材料拿過來。
老闆首先取一頁放在左邊,然後兩頁放在右邊,再然後兩頁左邊,兩頁右邊…… 排序速度瞬間翻倍 ……
(有網友評論提醒:這是歸納,不是排序)
下面是其他網友的回答:
慢排序
這是一個非常幽默卻沒什麼用的排序演算法。它基於“合而不治”的原則(分治演算法基本思想“分而治之”的反義詞,文字遊戲),它由 Andrei Broder 和 Jorge Stolfi 於 1986 年發表在論文《Pessimal Algorithms and Simplexity Analysis(最壞排序和簡單性分析)》中,虛擬碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function slowSort(array,start,end){ if( start >= end ) return; //已經不能再慢了 middle = floor( (start+end)/2 ); //遞迴 slowSort(array,start,middle); slowSort(array,middle+1,end); //比較得出最大值放在隊尾 if( array[end] < array[middle] ) swap array[end] and array[middle] //去掉最大值之後再排序 slowsort(array,start,end-1); } |
- 遞迴排序好前一半
- 遞迴排序好後一半
- 比較中間和隊尾的值,得到整個陣列的最大值,將最大值放到隊尾。
- 去掉最大值,遞迴整個陣列
Stack 排序
從 StackOverflow 上搜尋標題含有“陣列排序”的帖子,複製貼上並執行其中的程式碼片段,直到陣列排好序。我認為這種排序演算法事實上驗證了整個陣列。它被髮表在xkcd網站上,這裡有一個線上版的具體實現stacksort
隨機排序
執行如下: 建立一個隨機程式。 傳入陣列並執行隨機程式。 如果程式的輸出恰好是排好序的,完成。 否則重複上面過程。
太陽能位元翻轉排序
太陽發出的阿爾法粒子偶爾能夠翻轉記憶體中的位元位,所以這種演算法主要基於希望這種翻轉能夠使元素正確排序。執行方式如下:
檢查陣列是否排好序。 如果排好序,返回這個陣列。 如果沒有,等 10 秒鐘並祈禱太陽輻射使得位元位翻轉,而且使得陣列排好序,重複第一步。
義大利麵排序
這是一種線性時間演算法,是需要 O(n) 空間的穩定排序。它需要並行處理器。簡單來說,假設我們排序一列自然數。排序方法需要使用很多根生的義大利麵條。
將資料按比例轉換成表示義大利麵條長度的數字。 在每根麵條上寫下數字,並將麵條折斷成數字表示的長度。 把所有面條攥成一捆並把底部在平面上敲擊。 取出最突出的一根麵條,也就是最長的一根,獲取上面的數字,轉換成原始的資料並記錄下來。 重複這個過程直到處理完所有義大利麵。
指鹿為馬排序
這個演算法時間複雜度 O(n)。 聚集一幫人並向他們展示陣列。 詢問他們這個陣列是否是排序好的。 幹掉其中認為沒有排序好的人。 重複幾次,直到所有人同意這個陣列是排序好的。
智慧設計排序
無論你的陣列狀態是什麼樣的,它都算是排好序的。 解釋:原始輸入按照某種順序的概率是 1/(n!)。概率是如此小,(當前的順序)歸結於運氣成分顯然是荒謬的,所以它是按照“智慧設計”排序過的。所以完全可以說陣列已經排好序了,只是不是我們傳統意義上的“升序”。如果按照我們傳統觀點對它進行操作,只會讓它亂序。(“智慧設計”涉及宗教和哲學,不過多解釋)
網際網路排序
這是一種氣泡排序,但每次比較都依靠網際網路的搜尋。比如 “0.211 和 0.75 哪個大?”
委員會排序
排序一個包含 N 個自然數的陣列,首先用紙列印出 N 份整個陣列。 然後在辦公室周圍選擇幾個恰好路過的倒黴委員。每個委員對應陣列中的一個數字。 給每個委員一份列印的陣列,並讓他們通過開會或其他手段,來決定自己代表的數字應該在有序陣列中的位置。 當這些委員有結論並答覆你時,陣列自然排好序了。
打賞支援我翻譯更多好文章,謝謝!
打賞譯者
打賞支援我翻譯更多好文章,謝謝!
任選一種支付方式