打乱一个有序数组

作者: 柯琦 | 来源:发表于2019-04-11 15:13 被阅读0次

sort方法

let arr = [1,2,3,4,5,6,7,8,9,10];
arr.sort(()=>{
    return 0.5-Math.random();
})

Fisher–Yates shuffle洗牌算法

首先我们有一个已经排好序的数组

1 2 3 4 5 6 7 8 9

1.从数组末尾开始,选区最后一个元素

1 2 3 4 5 6 7 8 【9】

在数组一共 9 个位置中,随机产生一个位置,该位置元素与最后一个元素进行交换,如下:
随机产生的位置为【2】,即arr[2]

1 2 [3] 4 5 6 7 8 【9】

交换位置:

1 2 [9] 4 5 6 7 8 【3】

2.接下来从数组倒数第二个元素开始进行上述操作:

现在数组如下括号内代表已随机后的元素:

1 2 9 4 5 6 7 【8】 (3)

在数组除去最后一元素的8 个位置中,随机产生一个位置,该位置元素与最后一个元素进行交换,如下:
随机产生的位置为【5】,即arr[5]

1 2 9 4 5 [6] 7 【8】 (3)

交换位置:

1 2 9 4 5 [8] 7 【6】 (3)

3.其实可以看到只要重复第一步操作,既可以将数组乱序排列

现在数组如下:

1 2 9 4 5 8 7 (6 3)

代码是实现

function shuffle(arr) {
  let length = arr.length,
    randomIndex,
    temp;
  while (length) {
    randomIndex = Math.floor(Math.random() * length--);
    temp = arr[length];
    arr[length] = arr[randomIndex];
    arr[randomIndex] = temp;
  }
  return arr;
}

let arr = [1, 2, 3, 4, 5, 6, 7, 8];
console.log(shuffle(arr));

使用正向for循环

function shuffleFor(arr) {
  let length = arr.length,
    randomIndex,
    temp;
  for (var i = 0; i < length; i++) {
    randomIndex = Math.round(Math.random() * (length - 1 - i)) + i;
    temp = arr[i];
    arr[i] = arr[randomIndex];
    arr[randomIndex] = temp;
  }
  return arr;
}
let arr1 = [1, 2, 3, 4, 5, 6, 7, 8];
console.log(shuffleFor(arr1));

代码可优化:

temp = arr[length];
arr[length] = arr[randomIndex];
arr[randomIndex] = temp;
//可以这样写
[arr[randomIndex],arr[length]]=[arr[length],arr[randomIndex]]

优化后

function shuffleSimple(arr) {
  for (var i = 0; i < arr.length; i++) {
    const randomIndex = Math.round(Math.random() * (arr.length - 1 - i)) + i;
    [arr[i], arr[randomIndex]] = [arr[randomIndex], arr[i]];
  }
  return arr;
}
let arr2 = [1, 2, 3, 4, 5, 6, 7, 8];
console.log(shuffleSimple(arr2));

相关文章

  • 打乱一个有序数组

    sort方法 Fisher–Yates shuffle洗牌算法 首先我们有一个已经排好序的数组 1.从数组末尾开始...

  • 常用算法目录

    数组 实现一个支持动态扩容的数组 实现一个大小固定的有序数组,支持动态增删改操作 实现两个有序数组合并为一个有序数...

  • 数据结构和算法必知必会的50个实现

    数组 实现一个支持动态扩容的数组 实现一个大小固定的有序数组,支持动态增删改操作 实现两个有序数组合并为一个有序数...

  • 数据结构-Java 02.习题汇总1

    1. 合并两个有序的数组 给出两个有序的整数数组A和B,请将数组B合并到数组A中,变成一个有序的数组。注意:可以假...

  • LeetCode--两个有序数组合并

    题目: 如何将两个有序数组合并成一个有序数组 思路: 1:首先初始化 辅助数组,该数组存储的是两个有序数组的所有数...

  • 两个有序数组合并

    描述 给出一个整数数组 和有序的整数数组 ,请将数组 合并到数组 中,变成一个有序的升序数组注意:1.可以假设 数...

  • 常见算法

    1. 将两个有序数组合成为一个有序数组

  • LeetCodeDay23 —— 打家劫舍

    384. 打乱数组 描述 打乱一个没有重复元素的数组。 示例 思路 洗牌算法,每次从当前数组中随机一个元素与末尾元...

  • JS语法基础(四)之数组

    数组:使用一个变量来管理多个(一组)数据,方便维护和操作。 数组是一组有序的(数组的编号有序)数据的集合 有序:数...

  • 6_4循环有序数组最小值

    对于一个有序循环数组arr,返回arr中的最小值。有序循环数组是指,有序数组左边任意长度的部分放到右边去,右边的部...

网友评论

    本文标题:打乱一个有序数组

    本文链接:https://www.haomeiwen.com/subject/ioitwqtx.html