JavaScript随机打乱数组排序的几个方法

前言

  • 在网上看到一个简单但很经典的题目,就是给一个数组,要求将数组元素的排序随机打乱,实现的方法有很多,最受推崇的方法还是Fisher–Yates shuffle洗牌算法。下面会依次介绍三个方法,均能完成功能,各种区别
一个不太好的实现
  • 这是我看完题目后马上想到的一个方法,每次从原数组中随机取出一项,放进结果数组,直到原数组内的元素全部取出。这个方法很明显的一个缺陷就是:需要另外再声明一个数组变量,也算占用了额外的内存地址。
function getRandom (arr) {
  let dp = [...arr]
  let result = []
  while (dp.length > 0) {
    let randomIndex = Math.floor(Math.random() * (dp.length))
    result.push(dp.splice(randomIndex, 1)[0])
  }
  return result
}
一个抖机灵的实现
  • 还有一个抖机灵的实现方法,利用数组的sort排序方法。每次调用Math.random生成的随机数去和0.5作比较,来实现元素位置的重新排序。缺点在于相比其他两个方法,运算时间更长(待验证)。
function getRandom (arr) {
    let dp = [...arr]
    return dp.sort(() => Math.random() < .5)
}
Fisher–Yates shuffle
  • 具体内容可以去看它的维基百科,我这里直接说下他的实现原理:
    • 倒序循环这个数组
    • 取 范围从 1到n 的随机数 k
    • k 与 n 做交换
    • 直到循环到数组的首个元素
  • 相比第一个方法,就不需要定义额外的变量,每次对元素进行两两位置的交换,时间复杂度同样为O(n),下面是具体代码:
function shuffle (arr) {
  let res = [...arr]
  for (let i = arr.length - 1; i > 0; i--) {
    let randomIndex = Math.floor(Math.random() * (i + 1))
    let randomItem = res[randomIndex]
    res[randomIndex] = res[i]
    res[i] = randomItem
  }
  return res
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 最近看了一篇非常有趣的文章:关于JavaScript的数组随机排序,其作者为oldj前辈。文中指出我们用来“将一个...
    LucasHC阅读 658评论 0 6
  • 1 初级排序算法 排序算法关注的主要是重新排列数组元素,其中每个元素都有一个主键。排序算法是将所有元素主键按某种方...
    深度沉迷学习阅读 1,617评论 0 1
  • 1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 将一个记录插入到已排序好...
    依依玖玥阅读 1,357评论 0 2
  • 最近做音乐播放器,基本功能已实现,准备再写一个循环播放功能,其中涉及列表循环、单曲循环、随机循环。实现这几个功能本...
    _Dot912阅读 6,076评论 3 6
  • 概述:排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    每天刷两次牙阅读 3,829评论 0 15

友情链接更多精彩内容