如何在 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 ]
廣告
資料結構
網路
關係型資料庫管理系統
作業系統
Java
iOS
HTML
CSS
Android
Python
C 語言程式設計
C++
C#
MongoDB
MySQL
Javascript
PHP