出列排序。說說你會如何將一副撲克牌排序(花色順序是黑桃、紅桃、梅花和方片),限制條件是隻能查看最上面的兩張牌,交換最上面的兩張牌,或是將最上面的一張牌放到這摞牌的最下面。算法
以冒泡排序的思路處理,可是因爲只能看兩張牌,因此在排序過程當中是沒法斷定排序是否提早完成。bash
// 僞代碼
N = 52 // 總牌數
S = 0 // 已經排序整齊的牌數
for (1 到 N -1) {
// 作 N - 1 輪排序,每輪排序都能找到一張最小牌
for (1 到 N) {
// 每輪 N 次交換或移動
if (前兩張牌都是未排列整齊的牌) {
比較後將大的放到最下面(在未排列整齊的牌裏找小牌)
if (一旦前兩張牌中出現排列整齊的牌) {
比較後將小的牌放到最下面
}
}
}
將最上面的一張牌放到最後
排序完成
複製代碼
咱們假設只有 5 張牌,來看看具體會變成什麼樣子。less
初始順序 -> 4 2 5 3 1
第1輪排序
比較並移動大牌 -> 2 5 3 1 4
比較並移動大牌 -> 2 3 1 4 5
比較並移動大牌 -> 2 1 4 5 3
比較並移動大牌 -> 1 4 5 3 2 // 此時最上面的牌最小
比較並移動小牌 -> 4 5 3 2 1 // 因此改成比較小牌
第2輪排序
// 太巧合了 0,0 看上去雖然順了,但實際咱們只能看到前兩張牌,因此是這樣的 4 3 * * *
比較並移動大牌 -> 4 3 2 1 5
比較並移動大牌 -> 3 2 1 5 4
比較並移動大牌 -> 2 1 5 4 3 // 此時最上面的牌第二小
比較並移動小牌 -> 2 5 4 3 1 // 因此改成比較小牌
比較並移動小牌 -> 5 4 3 1 2
第3輪排序
比較並移動大牌 -> 4 3 1 2 5
比較並移動大牌 -> 3 1 2 5 4 // 此時最上面的牌第三小
比較並移動小牌 -> 3 2 5 4 1 // 因此改成比較小牌
比較並移動小牌 -> 3 5 4 1 2
比較並移動小牌 -> 5 4 1 2 3
...
複製代碼
每次第 n 輪結束時,牌堆最後 n 張牌都是從小到大排序整齊的了。ui
因此在 n - 1輪結束時,牌堆最上面的一張牌是最大的牌,其他 n - 1 張牌都是從小大排序整齊的,直接將最上面的牌放到最下面排序就完成了。spa
第3輪排序結束時 -> 5 4 1 2 3
第4輪排序
比較並移動大牌 -> 4 1 2 3 5 // 此時最上面的牌第四小
比較並移動小牌 -> 4 2 3 5 1 // 因此改成比較小牌
比較並移動小牌 -> 4 3 5 1 2
比較並移動小牌 -> 4 5 1 2 3
比較並移動小牌 -> 5 1 2 3 4
第5輪排序
移動最上面一張 -> 1 2 3 4 5
排序完成
複製代碼
let array = [...] // 牌堆
function less (a, b) {...} // 比較 a 是否小於 b,並返回布爾值
function exch (array, i, j) {...} // 交換 array 中 i 和 j 的值
let N = array.length;
for (let i = 1; i < N - 1; i++) {
for (let j = 0; j < N; j++) {
if (j < (N - 1 - i)) {
if (less(array[0], array[1])) {
exch(array, 0, 1);
}
} else {
if (less(array[1], array[0])) {
exch(array, 0, 1);
}
}
array.push(array.shift());
}
}
array.push(array.shift());
複製代碼
CodePencode
若是喜歡文章 請留下一個贊~ 若是喜歡文章 分享給更多人~cdn
自由轉載-非商用-非衍生-保持署名(創意共享3.0許可證) 轉載時請保留原文連接 以保證可及時獲取對文章的訂正和修改排序