如何在 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