JS中数组随机排序实现(原地算法sort/shuffle算法)

news2025/7/19 2:38:19

🐱个人主页:不叫猫先生
🙋‍♂️作者简介:专注于前端领域各种技术,热衷分享,期待你的关注。
💫系列专栏:vue3从入门到精通
📝个人签名:不破不立

目录

  • 一、原地算法
  • 二、Array.property.sort()
    • 1、方法一(不推荐)
    • 2、方法一改良
  • 三、洗牌算法实现随机排序
    • 1、换牌
    • 2、抽牌
  • 附:本文用到的JS基础

一、原地算法

在谈sort之前,我们先了解一下原地算法,什么事原地算法呢?所谓原地算法就是说基于原有的数据结构进行一定的操作修改,而不借助额外的空间。使用原地算法时,其内存干净,空间复杂度是O(1),可以减少没必要的内存,避免造成内存浪费和冗余。当然,减小内存损耗会带来算法复杂度和时间消耗的增加,所以是一个Tradeoff。Tradeoff 是一种针对目标选择有效的路径的思维方式,需要对做的事情权衡利弊,选择最佳方式处理问题。

二、Array.property.sort()

含义:sort方法基于原地算法实现数组排序,直接对数据进行排序
参数:sort(compare(a,b)),指定顺序对数组进行排序,不写参数的时候,默认会将原数据转换成字符串按照字符的Unicode编码进行排序。

compare(a,b)中,a、b都是比较参数,当
a-b>0 ,交换位置
a-b=0,位置不变
a-b<0,位置不变

随机排序我们都会想到Math的random方法,具体实现如下,但是这样操作确有缺陷,理论很丰满,实践很残酷。

1、方法一(不推荐)

arr.sort(() => Math.random() - 0.5)
  • 缺陷:chrome浏览器对于数组长度为10以内的使用插入排序,反之则为快速排序和插入排序的组合,故而并不能做到随机分布。
  • 测试:测试某数据在数组中各个位置的次数。
        let obj = {};
		let count = 0;
		let n = 10000;
		while (n--) {
			let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14]
			arr.sort(() => Math.random() - 0.5)
			let index = arr.indexOf(1)//取1在数组排序后的位置
			obj[index] ? obj[index]++ : obj[index] = 1
		}
  • 输出:
    在这里插入图片描述
  • 图示:
    在这里插入图片描述

ECMAScript中关于Array.prototype.sort(comparefn)的标准,其中并没有规定具体的实现算法,但是提到一点: Calling comparefn(a,b) always returns the same value v when given a specific pair of values a and b as its two arguments.也就是说,对同一组a、b的值,comparefn(a, b)需要总是返回相同的值。而上面的() => Math.random() -0.5(即(a, b) => Math.random() - 0.5)显然不满足这个条件。 翻看v8引擎数组部分的源码,注意到它出于对性能的考虑,对短数组(例如长度小于10)使用的是插入排序,对长数组则使用了快速排序。

理解:(a, b) => Math.random() - 0.5,每次a,b都是固定的,但是Math.random() - 0.5)却是随机的,

2、方法一改良

构造一个新数组,如[{v:1,k:Math.random()},{v:1,k:Math.random()}],具体如下:

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14]
for(let i=0;i<arr.length;i++){
    shuffle(arr)
}
function shuffle(arr){
   let newArr = arr.map(item=>({v:i,k:Math.random())})
   newArr.sort((a,b)=> (a.k - b.k))
   arr.splice(0, arr.length, ...newArr.map(i => i.v));
}

三、洗牌算法实现随机排序

1、换牌

逻辑:从一副牌中抽取一张,与最后一张牌进行交换,放到最后证明该牌已经被随机抽选过,而被交换的牌就排在前面,就有机会被继续抽选。

  • 随机抽取一张
  • 抽取的放置到最后位置
  • 最后位置的牌放置在随机抽取的位置
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14];
funtion shuffle(ar){
   for(let i = arr.length;i>0;i--){
      let temRandom =  Math.floor(Math.random()*i)
      arr[i] = arr[temRandom];
      arr[temRandom] = arr[i]
   }
   return arr
}
shuffle(arr)

2、抽牌

逻辑:从一副牌抽取一张放置一旁,则这幅牌会越抽越少,直至到最后一张。

  • 随机抽取一张
  • 抽取的牌放置旁边
  • 在抽取的那副牌冲除去随机抽取的那张牌
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14];
funtion shuffle(ar){
   let temp = [];
   for(let i = arr.length;i>0;i--){
      let temRandom =  Math.floor(Math.random()*i)
      temp.push(arr[temRandom])
      arr.splice(temRandom,1)//抽取一张后,要除去这张牌,然后在剩下的牌中继续抽
   }
   return temp
}
shuffle(arr)

附:本文用到的JS基础

本文用到数组方法基本介绍

  • splice返回被删除的元素,直接修改数组数据,可接受1/2/3个参数
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14];
arr.splice(0)//删除索引从0开始的所有数据,即删除所有数据
arr.splice(0)//删除索引从1开始的所有数据,即只保留第一位数据
arr.splice(2,1)//删除索引为2的数据
arr.splice(0,arr.length,5)//删除原数组的数据,并把数据5填充到arr中
  • Math.floor() 向下取整
  • Math.ceil() 向上取整

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/37986.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码随想录刷题|LeetCode 70. 爬楼梯(进阶) 322. 零钱兑换 279.完全平方数 139.单词拆分

目录 70. 爬楼梯 &#xff08;进阶&#xff09; 思路 爬楼梯 1或2步爬楼梯 多步爬楼梯 322. 零钱兑换 思考 1、确定dp数组及其含义 2、确定递推公式 3、初始化dp数组 4、确定遍历顺序 零钱兑换 先遍历物品&#xff0c;再遍历背包 先遍历背包&#xff0c;再遍历物品 279.完全平方…

【操作系统实验】线程的创建+信号量通信

sem_init: 功能&#xff1a;初始化信号量 返回值&#xff1a;创建成功返回0&#xff0c;失败返回-1 参数sem&#xff1a;指向信号量结构的一个指针 参数pshared&#xff1a;不为&#xff10;时此信号量在进程间共享&#xff0c;为0时当前进程的所有线程共享 参数value&#xf…

react context原理

带着问题思考&#xff1a; 1 Provder 如何传递 context&#xff1f;2 三种获取 context 原理 &#xff08; Consumer&#xff0c; useContext&#xff0c;contextType &#xff09;&#xff1f;3 消费 context 的组件&#xff0c;context 改变&#xff0c;为什么会订阅更新 &a…

Vue+iview将表格table以excel文件导出的几种方式

前言 在日常工作中&#xff0c;若是经常跟后台管理系统打交道的朋友想必对导出excel表格这种需求肯定很熟悉吧。不过我也问了身边的一些岗位为后端工程师的朋友&#xff0c;他们说在公司的话一般导出excel表格的工作一般由后端来做&#xff0c;前端只需要调用接口即可。我的话…

AI面试必备-《家居必备的AI精选资源列表》免费分享

本资源介绍 DeepMind科学家和工程师为有兴趣了解更多人工智能、机器学习和其他相关主题的学生整理的教育资源列表。 文末附本书免费获取地址。 内容截图 本资源免费下载地址 链接: https://pan.baidu.com/s/1IkPk0a3q2Z1z4FATG2y7HA?pwdwy3c 提取码: wy3c 往期精品内容推荐 大…

认知电子战 | 无线电中的认知理论

认知的概念 认知(Cognition)是指人认识外界事务的过程 认知本来是用于描述具有生命特征的物种的,借用于机器或系统上,就是指将认知的思想应用于机器上。 生物的认知特点: 感觉思考、推理、问题解答判断记忆分别对应于系统认知特点: 感知(各种传感器)机器学习算法、基…

算法提升:图的启发式搜索算法(A算法、A*算法)

启发式搜索算法 目录 概念 A算法 A*算法 概念 启发式搜索(Heuristically Search)又称为有信息搜索(Informed Search)&#xff0c;它是利用问题拥有的启发信息来引导搜索&#xff0c;达到减少搜索范围、降低问题复杂度的目的&#xff0c;这种利用启发信息的搜索过程称为启发…

修改 Git 已经提交记录的 用户名 和邮箱

修改 Git 已经提交记录的 用户名 和邮箱 有关 Git 和版本控制的常见问题。 如何更改提交的作者姓名/电子邮件&#xff1f; 在我们进入解决方案之前&#xff0c;让我们找出您到底想要完成什么&#xff1a; 在提交之前更改作者信息在提交后更改作者信息&#xff08;即历史提交…

常见的前端安全问题(xss / csrf / sql / ddos / cdn...)

目录 1. xss&#xff08;Cross Site Scripting&#xff09;跨站脚本攻击 1.1 持久型&#xff08;存储型&#xff09;攻击 / 非持久型&#xff08;反射型&#xff09;攻击 是什么&#xff1f; 1.2 xss 出现的场景&#xff1f;造成的危害&#xff1f; 1.3 防御 xss&#xff0…

three.js之Geometry顶点、颜色数据与三角面

文章目录简介顶点对于代码的解释颜色对于代码的解释三角面专栏目录请点击 简介 Geometry与BufferGeometry表达的含义相同&#xff0c;只是对象的结构不同three.js渲染的时候会先把Geometry转化为BufferGeometry在解析几何体顶点数据进行渲染 顶点 <!DOCTYPE html> <…

基于JavaWeb的药品进销存管理系统(JSP)

目 录 绪论 1 1.1 本课题的研究背景 1 1.2 国内外研究现状 1 1.3 本课题的主要工作 2 1.4 目的和意义 2 开发工具及技术 3 2.1 开发工具 3 2.1.1 MyEclipse 3 2.1.2 Tomcat 3 2.1.3 Mysql 3 2.2 开发技术 4 2.2.1 JSP 4 2.2.2 MyBatis 4 2.2.3 JavaScript 4 2.2.4 jQuery以及j…

机械原理-试题及答案

模拟试题八&#xff08;机械原理A&#xff09; 一、判断题&#xff08;10分&#xff09;[对者画√&#xff0c;错者画 ] 1、对心曲柄滑块机构都具有急回特性。&#xff08; &#xff09; 2、渐开线直齿圆柱齿轮的分度圆与节圆相等。&#xff08; &#xff09; 3、当两直齿圆柱齿…

Spring Cloud OpenFeign - 日志配置

项目源码地址&#xff1a;https://download.csdn.net/download/weixin_42950079/87168704 OpenFeign 有 4 种日志级别&#xff1a; NONE: 不记录任何日志&#xff0c;是OpenFeign默认日志级别&#xff08;性能最佳&#xff0c;适用于生产环境&#xff09;。BASIC: 仅记录请求方…

[附源码]计算机毕业设计JAVA人力资源管理系统论文2022

[附源码]计算机毕业设计JAVA人力资源管理系统论文2022 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM…

QT对象树和菜单操作

前言 可以与MFC框架进行比较&#xff0c;总结彼此的相同点和不同点&#xff0c;在此基础上再去学习其他的界面框架&#xff0c;达到增量学习的境界。 一.对象树 优点&#xff1a;当父对象被析构时&#xff0c;如果子对象没有被析构&#xff0c;QT的对象树机制会去析构它&…

pandas索引操作、赋值操作、排序以及Series排序和DataFrame排序

一、pandas索引操作 索引操作&#xff0c;使用索引选取序列和切片选择数据&#xff0c;也可以直接使用列名、行名称&#xff0c;或组合使用 直接使用行列索引&#xff1a;行列索引名顺序为先列再行&#xff0c;使用指定行列索引名&#xff0c;不能使用下标loc[行索引名&#…

MySQL数据库表空间回收问题

MySQL数据库表空间回收问题1. MySQL表空间回收2. MySQL表空间设置3. MySQL删除数据流程4. MySQL数据页空洞问题1. MySQL表空间回收 我们经常会发现一个问题&#xff0c;就是把表数据删除以后发现&#xff0c;数据文件大小并没有变化&#xff0c;这就是标题中所说的MySQL数据库…

Numpy数组中的维度和轴

维度究竟是行数还是列数&#xff1f; m维行向量&#xff1a;m维表示一行中有m列&#xff0c;由于是行向量&#xff0c;所以是1行m列n维列向量&#xff1a;n维表示一行中有n行&#xff0c;由于是列向量&#xff0c;所以是n行1列m维向量&#xff1a;看书的习惯了&#xff0c;一般…

APS生产计划排产 — 排产结果拉动模具工装需求计划

APS生产计划排产系统&#xff0c;对所有资源具有同步的&#xff0c;实时的&#xff0c;具有约束能力的&#xff0c;模拟能力&#xff0c;不论是物料&#xff0c;机器设备&#xff0c;人员&#xff0c;供应&#xff0c;客户需求&#xff0c;运输等影响计划因素。不论是长期的或短…

【CNN-SVM回归预测】基于CNN-SVM实现数据回归预测附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …