如何在 JavaScript 中實現蝴蝶洗牌演算法?


在 JavaScript 中,蝴蝶洗牌陣列是指一個數字陣列,其排序方式為:越靠近陣列中心,數字越小;越靠近陣列兩端,數字越大。最大的數字位於第一個索引位置。

蝴蝶洗牌陣列的另一種變體是:越靠近陣列中心,數字越大;越靠近陣列兩端,數字越小。在這種情況下,最小的數字位於第一個索引位置。

對於有數學背景的人來說,這與高斯分佈有些相似。

示例

假設我們有以下陣列:

const arr = [8,2,6,3,9,1,4,5,0,7];

如果我們對其應用蝴蝶洗牌演算法,輸出將為:

[9, 7, 5, 3, 1,0, 2, 4, 6, 8]

可以看到,最大和第二大的數字位於陣列的兩端,最小的數字位於陣列的中心。

另一種可能性是:

[0, 2, 4, 6, 8, 9, 7, 5, 3, 1]

我們的任務是編寫一個函式,該函式接收一個數字陣列和一個字串作為第二個引數,字串可以取兩個值中的任何一個:“asc” 或 “des”。

  • 如果字串為“des”,則我們必須按升序到降序的順序對陣列進行洗牌。

  • 如果字串為“asc”,則我們必須按降序到升序的順序對陣列進行洗牌。

方法

  • 如果字串為“asc”,我們首先按升序對陣列進行排序,否則按降序排序。因此,假設函式被呼叫時帶了“asc”,那麼陣列現在將如下所示:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  • 然後我們將陣列分成兩個陣列,使相鄰元素分佈在不同的陣列中。我們將元素推入一個數組,同時將其移到另一個數組的開頭,這樣一來,一個數組就會被反轉,而無需我們手動進行反轉操作。

這樣形成的兩個陣列將如下所示:

[ 0, 2, 4, 6, 8 ] [ 9, 7, 5, 3, 1 ]
  • 現在,最後一步是連線這兩個陣列,之後我們將得到所需的陣列。將所有這些程式碼放在一起,看起來就像這樣:

示例

const array = [8,2,6,3,9,1,4,5,0,7];
const butterflyShuffle = (array, order = 'asc') => {
   //creating a new copy of array so that we dont mutate the original
array
   const arr = array.slice();
   //sorting ascending or descending based on the argument
   arr.sort((a, b) => order === 'asc' ? a-b : b-a);
   const first = [], second = [];
   //this variable will later help in determining which array is to be
reversed
   //and which one is to be concatenated to which
   //if length is even, it means that last element will go in second array
   //otherwise it will go in first array
   const isEven = arr.length % 2 === 0;
   for (let i = 0; i < arr.length; i++){
      if(i % 2 === 0){
         isEven ? first.push(arr[i]) : first.unshift(arr[i]);
         continue;
      };
      isEven ? second.unshift(arr[i]) : second.push(arr[i]);
   };
   return isEven ? second.concat(first) : first.concat(second);
};
console.log(butterflyShuffle(array));
console.log(butterflyShuffle(array, 'des'));

輸出

控制檯中的輸出將為:

[
   9, 7, 5, 3, 1,
   0, 2, 4, 6, 8
]
[
   0, 2, 4, 6, 8,
   9, 7, 5, 3, 1
]

更新於: 2020-08-25

296 次瀏覽

開啟你的 職業生涯

透過完成課程獲得認證

開始學習
廣告