前端对普通数字数组排序示例
1. arr.sort(fn)
// 升序排序arr.sort((a, b) => a - b);// 降序排序arr.sort((a, b) => b - a);
2. 冒泡排序
冒泡排序-升序原理:
eg: [1, 6, 7, 9, 10, 3, 4, 5, 2]
1) 先遍历第一遍数组, 前一个数字大于后一个数字, 就交换位置, 最后最大值10放在数组的最后, 此时是 [1, 6, 7, 9, 3, 4, 5, 2, 10];
for (let j = 0; j < arr.length-1; j++) {
preNum = arr[j];
const nextNum = arr[j + 1];
if (preNum > nextNum) { // 左边的数字大于右边的数字,交换位置
// 数字小的往前挪, 数字大的往后挪
arr[j] = nextNum;
arr[j + 1] = preNum;
}
}
2) 第二遍就是: 前一个数字大于后一个数字, 就交换位置, 最后第二大的值放在数组的倒数第二位, 此时是 [1, 6, 7, 3, 4, 5, 2, 9, 10];
for (let j = 0; j < arr.length-2; j++) {
preNum = arr[j];
const nextNum = arr[j + 1];
if (preNum > nextNum) { // 左边的数字大于右边的数字,交换位置
// 数字小的往前挪, 数字大的往后挪
arr[j] = nextNum;
arr[j + 1] = preNum;
}
}
3) 第三遍就是: 前一个数字大于后一个数字, 就交换位置, 最后第三大的值放在数组的倒数第三位, 此时是 [1, 6, 3, 4, 5, 2, 7, 9, 10];
for (let j = 0; j < arr.length-3; j++) {...}
以此类推...
4) 最后一遍: 前一个数字大于后一个数字, 就交换位置, 最后第2小的值放在数组的第2位, 此时是 [1, 2, 3, 4, 5, 6, 7, 9, 10]
for (let j = 0; j < 1; j++) {...}
5) 因为for (let j = 0; j < x; j++) {...}; 推导可知x的值范围是(0, arr.length-1];
所以:
for (let j = arr.length - 1; i > 0; i--) {
for (let j = 0; j < i; j++) {...}
}
排序.js:14 第1次计算:
- (9) [1, 6, 7, 9, 3, 4, 5, 2, 10]
排序.js:14 第2次计算:
- (9) [1, 6, 7, 3, 4, 5, 2, 9, 10]
排序.js:14 第3次计算:
- (9) [1, 6, 3, 4, 5, 2, 7, 9, 10]
排序.js:14 第4次计算:
- (9) [1, 3, 4, 5, 2, 6, 7, 9, 10]
排序.js:14 第5次计算:
- (9) [1, 3, 4, 2, 5, 6, 7, 9, 10]
排序.js:14 第6次计算:
- (9) [1, 3, 2, 4, 5, 6, 7, 9, 10]
排序.js:14 第7次计算:
- (9) [1, 2, 3, 4, 5, 6, 7, 9, 10]
排序.js:14 第8次计算:
- (9) [1, 2, 3, 4, 5, 6, 7, 9, 10]
最后一次不用计算了, 最小值就是1
[1, 2, 3, 4, 5, 6, 7, 9, 10]
冒泡排序--普通双层遍历循环版本:
// 冒泡排序-升序
const bubleSort = (arr) => {let preNum = null;// 之所以i>0, 因为排序交互位置到最后两个的时候, 只需要比较一次就行了, 最后那个数字不必比较了for (let i = arr.length - 1; i > 0; i--) {for (let j = 0; j < i; j++) {preNum = arr[j];const nextNum = arr[j + 1];if (preNum > nextNum) { // 左边的数字大于右边的数字,交换位置// 数字小的往前挪, 数字大的往后挪arr[j] = nextNum;arr[j + 1] = preNum;}}}return arr;
}// 冒泡排序-降序
const bubleSort = (arr) => {let preNum = null;// 之所以i>0, 因为排序交互位置到最后两个的时候, 只需要比较一次就行了, 最后那个数字不必比较了for (let i = arr.length - 1; i > 0; i--) {for (let j = 0; j < i; j++) {preNum = arr[j];const nextNum = arr[j + 1];if (preNum < nextNum) { // 左边的数字小于右边的数字,交换位置// 数字大的往前挪, 数字小的往后挪arr[j] = nextNum;arr[j + 1] = preNum;}}}return arr;
}
冒泡排序-升序-递归
// 冒泡排序-升序
const bubleSort0 = (arr, i = arr.length - 1) => {let preNum = null;// 之所以i>0, 因为排序交互位置到最后两个的时候, 只需要比较一次就行了, 最后那个数字不必比较了for (let j = 0; j < i; j++) {preNum = arr[j];const nextNum = arr[j + 1];if (preNum > nextNum) { // 左边的数字大于右边的数字,交换位置// 数字小的往前挪, 数字大的往后挪arr[j] = nextNum;arr[j + 1] = preNum;}}i--;if (i > 0) return bubleSort0(arr, i);return arr
}// 冒泡(升序排序)
var arr = bubleSort0([1, 6, 7, 9, 10, 3, 4, 5, 2])
console.log(arr, '冒泡排序-升序-递归');// 冒泡排序-降序
const bubleSort0 = (arr, i = arr.length - 1) => {let preNum = null;// 之所以i>0, 因为排序交互位置到最后两个的时候, 只需要比较一次就行了, 最后那个数字不必比较了for (let j = 0; j < i; j++) {preNum = arr[j];const nextNum = arr[j + 1];if (preNum < nextNum) { // 左边的数字小于右边的数字,交换位置// 数字大的往前挪, 数字小的往后挪arr[j] = nextNum;arr[j + 1] = preNum;}}i--;if (i > 0) return bubleSort0(arr, i);return arr
}// 冒泡(降序排序)
var arr = bubleSort0([1, 6, 7, 9, 10, 3, 4, 5, 2])
console.log(arr, '冒泡排序-升序-递归');
3. 选择排序
eg: [6, 7, 9, 10, 3, 4, 5, 2, 1]
当i等于0时:
1) min=第一个元素6, 和数组其余的元素比较, 原本的第一位元素6在if (nextNum < preNum){...}中6和第一个比6小的元素3交换了位置,此时是[3, 7, 9, 10, 6, 4, 5, 2, 1];
2) min变成3, 比3小的第一个元素是2, 此时是[2, 7, 9, 10, 6, 4, 5, 3, 1];
3) min变成2, 比2小的元素是1, 所以交换位置, 此时是[1, 7, 9, 10, 6, 4, 5, 3, 2];
5) 往右数没有比1小的元素了, 结束
当i等于1时:
1) min=数组第二个元素7, 和第三个及之后的元素比较, 第一个比7小的元素是6, 交换位置, 此时是: [1, 6, 9, 10, 7, 4, 5, 3, 2];
2) min变成6, 比6小的第一个元素是4, 此时是[1, 4, 9, 10, 7, 6, 5, 3, 2];
3) min变成4, 比4小的第一个元素是3, 此时是[1, 3, 9, 10, 7, 6, 5, 4, 2];
4) min变成3, 比3小的第一个元素是2, 此时是[1, 2, 9, 10, 7, 6, 5, 4, 3];
5) 往右数没有比2小的元素了, 结束
当i等于2时:
1) min等于数组第三个元素9, 和第四个及之后的元素比较, 第一个比9小的元素是7, 此时是[1, 2, 7, 10, 9, 6, 5, 4, 3];
2) min变成7, 比7小的第一个元素是6, 此时是[1, 2, 6, 10, 9, 7, 5, 4, 3];
3) min变成6, 比7小的第一个元素是5, 此时是[1, 2, 5, 10, 9, 7, 6, 4, 3];
4) min变成5, 比7小的第一个元素是4, 此时是[1, 2, 4, 10, 9, 7, 6, 5, 3];
5) min变成4, 比4小的第一个元素是3, 此时是[1, 2, 3, 10, 9, 7, 6, 5, 4];
5) 往右数没有比3小的元素了, 结束
以此类推...
所以:
// 小的越来越靠左, 以此类推
/**
* 选择排序:
原理: 给每个位置选择当前元素最小的;
* 比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,
* 直到第n-1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。
* 选择排序的本质: 每一次大循环就是选出最小的那个值,在选最小值的过程你可以通过下标记录
* 也可以每次交换值都可以
*/
选择排序-双层遍历版本:
// 选择排序-升序
const selectSort = arr => {const len = arr.length;for (let i = 0; i < len; i++) {let min = arr[i];for (let j = i + 1; j < len; j++) {const nextNum = arr[j];const preNum = min;// 如果当前的值比记录的最小值还要小, 就交换这2个数字的位置if (nextNum < preNum) {arr[j] = preNum;min = nextNum; // min被赋值为比较出来的较小值continue;}}arr[i] = min; // 因为min在内循环被修改了, 所以arr[i]的值应该在跳出内循环后在它自身循环体被修改}return arr
}// 选择(升序排序)
var arr = selectSort([6, 7, 9, 10, 3, 4, 5, 2, 1])
console.log(arr, '选择排序-升序');
选择排序-递归+for循环
// 选择排序
const selectSort0 = (arr, i=0) => {const len = arr.length;let min = arr[i];for (let j = i + 1; j < len; j++) {const nextNum = arr[j];const preNum = min;console.log(preNum, 'preNum=====')// 如果当前的值比记录的最小值还要小, 就交换这2个数字的位置if (nextNum < preNum) {arr[j] = preNum;min = nextNum; // min被赋值为比较出来的较小值continue;}}arr[i] = min; // 因为min在内循环被修改了, 所以arr[i]的值应该在跳出内循环后在它自身循环体被修改i++;if(i<=2) selectSort0(arr, i);return arr
}// 选择(升序排序)
var arr = selectSort0([6, 7, 9, 10, 3, 4, 5, 2, 1])
console.log(arr, '选择排序-升序00000');
4. 快速排序:
如果数组的元素个数小于2个, 返回原数组;
如果数组元素个数大于等于2个:
1) flag = 一个标尺元素(一般是第一个元素); left=flag左边的元素组成的数组(初始化); right=flag右边的元素组成的数组(初始化);
2) 遍历arr, 比flag小的push进left数组, 比flag大的push进right数组
3) 将left和right数组执行上述(1)和(2)步骤
4) 使用concat拼接left数组, flag, right数组
快速排序-for循环+递归+concat
// 快速排序
const quickSort = (arr) => {const len = arr.length;if (len < 2) {return arr;}// 选择标尺元素let flag = arr[0];let left = [];let right = [];let preNum = null;// 因为flag取的是下标0的元素, 所以遍历从下标1开始for (let i = 1; i < len; i++) {preNum = arr[i];if (preNum < flag) {// 比flag小的放左边left.push(preNum);}else {// 比flag大的放右边right.push(preNum);}}// 进行递归return quickSort(left).concat(flag, quickSort(right));
}
快速排序-划分交换in-place
// 快速排列in-place(交换)--划分交换排序:
const quickInPlaceSort = (arr) => {// 数组指定两个位置进行值交换let exchange = (arr, i, j) => {const preNum = arr[i];const nextNum = arr[j];arr[i] = nextNum;arr[j] = preNum;}// 完成一次划分交换let findCenter = (arr, leftIdx, rightIdx) => {let flag = arr[leftIdx];let centerIdx = leftIdx + 1;for (let i = centerIdx; i <= rightIdx; i++) {if (arr[i] < flag) {exchange(arr, centerIdx, i); // 交换位置centerIdx++; // 交换的下标+1}}exchange(arr, leftIdx, centerIdx - 1);return centerIdx;}// 递归排序let sort = (arr, leftIdx, rightIdx) => {if (leftIdx < rightIdx) {let center = findCenter(arr, leftIdx, rightIdx);sort(arr, leftIdx, center - 1);sort(arr, center, rightIdx);}}sort(arr, 0, arr.length - 1);return arr;
}
var arr = quickInPlaceSort([1, 6, 7, 9, 10, 3, 4, 5, 2]);
console.log(arr, '快速排序-升序-划分交换'); // [1, 2, 3, 4, 5, 6, 7, 9, 10] '快速排序-升序-划分交换'
console.log('-----------------------------------------');
相关文章:
前端对普通数字数组排序示例
1. arr.sort(fn) // 升序排序arr.sort((a, b) > a - b);// 降序排序arr.sort((a, b) > b - a); 2. 冒泡排序 冒泡排序-升序原理: eg: [1, 6, 7, 9, 10, 3, 4, 5, 2] 1) 先遍历第一遍数组, 前一个数字大于后一个数字, 就交换位置, 最后最大值10放在数组的最后, 此时是…...
SQL server中:常见问题汇总(如:修改表时不允许修改表结构、将截断字符串或二进制数据等)
SQL server中:常见问题汇总 1.修改表时提示:不允许修改表结构步骤图例注意 2.将截断字符串或二进制数据。3.在将 varchar 值 null 转换成数据类型 int 时失败。4.插入insert 、更新update、删除drop数据失败,主外键FOREIGN KEY 冲突5.列不允许…...
无线通信中CSI的含义
在无线通信中,CSI代表"Channel State Information",即信道状态信息。CSI是一种关键的信息,用于评估和描述通信信道的特性,以帮助发送器和接收器在通信过程中做出智能的调整和决策。 CSI包括有关通信信道的以下信息&…...
如何一键核实验证身份证的真伪?
据报道,今年10月10日,广东省佛山市朱某因生活琐事与丈夫发生争吵,民警发现她的身份证有问题。 在民警打算进一步了解情况,查看夫妻二人的身份证件时,朱某的身份证引起了民警的注意。这张身份证表面很光滑,…...
冒泡排序:了解原理与实现
目录 原理 实现 性能分析 结论 冒泡排序(Bubble Sort)是一种简单但效率较低的排序算法。它重复地比较相邻的元素并交换位置,直到整个序列有序为止。虽然冒泡排序的时间复杂度较高,但在小规模数据集上仍然具有一定的实际应用价…...
springboot maven项目环境搭建idea
springboot maven项目环境搭建idea 文章目录 springboot maven项目环境搭建idea用到的软件idea下载和安装java下载和安装maven下载和安装安装maven添加JAVA_HOME路径,增加JRE环境修改conf/settings.xml,请参考以下 项目idea配置打开现有项目run或build打…...
vue3检测是手机还是pc端,监测视图窗口变化
1.超小屏幕(手机) 768px以下 2.小屏设备(平板) 768px-992px 3.中等屏幕(旧式电脑) 992px-1200px 4.大屏设备(现代电脑) 1200px以上 <script setup name"welcome"> i…...
B - Magical Subsequence (CCPC2021哈尔滨)
思路: (1)问题:对于已知数组,每组依次选两个,尽量选更多组,选的每组和相等;(假定和为x) (2)于是问题拆分为两步, x是多少x确定时&a…...
Leetcode刷题详解——x的平方根
1. 题目链接:69. x 的平方根 2. 题目描述: 给你一个非负整数 x ,计算并返回 x 的 算术平方根 。 由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。 **注意:**不允许使用任何内置指数函数和…...
windows安装docker,解决require wsl 2问题
想在windows上安装桌面版docker,上官网下载了安装包,安装完后,启动报错,忘了截图了。 大概意思就是require wsl 2。 于是就是docker FAQ中找相关问题解决方案,点,点,点然后就点到微软了。 ws…...
建立复数类
目录 程序设计 程序分析 系列文章 在课堂示例的基础上,显示复数时如果虚部为0时只显示实部,实部为0时只显示虚部,虚部为负数时以a-bi的形式显示,并为复数类增加减法功能。 程序设计 Work4类: package work;import java.util.Scanner;public class Work4 {private in…...
docker部署prometheus+grafana服务器监控(三) - 配置grafana
查看 prometheus 访问 http://ip:9090/targets,效果如下,上面我们通过 node_exporter 收集的节点状态是 up 状态。 配置 Grafana 访问 http://ip:3000,登录 Grafana,默认的账号密码是 admin:admin,首次登录需要修改…...
面试题:说一下加密后的数据如何进行模糊查询?
文章目录 正文如何对加密后的数据进行模糊查询沙雕做法沙雕一沙雕二 常规做法常规一常规二超神做法 总结 正文 我们知道加密后的数据对模糊查询不是很友好,本篇就针对加密数据模糊查询这个问题来展开讲一讲实现的思路,希望对大家有所启发。 为了数据安…...
LeetCode75——Day15
文章目录 一、题目二、题解 一、题目 1456. Maximum Number of Vowels in a Substring of Given Length Given a string s and an integer k, return the maximum number of vowel letters in any substring of s with length k. Vowel letters in English are ‘a’, ‘e’…...
Qwt开发环境搭建(保姆级教程)
1.简介 QWT,即Qt Widgets for Technical Applications,其目标是以基于2D方式的窗体部件来显示数据, 数据源以数值,数组或一组浮点数等方式提供, 输出方式可以是Curves(曲线),Slider…...
【供应链】仓储、物流、车辆管理
...
从另外一个进程中读取数据
从另外一个进程中读取数据,其实就注入线程,寻址,解析内存,处理数据。例如这个就是从另外一个正在运行的进程中,读取数据并保存。实时性还可以。...
【FPGA零基础学习之旅#17】搭建串口收发与储存双口RAM系统
🎉欢迎来到FPGA专栏~搭建串口收发与储存双口RAM系统 ☆* o(≧▽≦)o *☆嗨~我是小夏与酒🍹 ✨博客主页:小夏与酒的博客 🎈该系列文章专栏:FPGA学习之旅 文章作者技术和水平有限,如果文中出现错误࿰…...
建立Line类
目录 程序设计 程序分析 系列文章 计算机上的线实际上是线段,要求包含两个端点;颜色为彩虹色;线的粗细是类变量,至少包含show方法。 程序设计 Work5类: package work;import java.util.Scanner;public class Work5 { public static void main(String[] args) {// …...
10_集成学习方法:随机森林、Boosting
文章目录 1 集成学习(Ensemble Learning)1.1 集成学习1.2 Why need Ensemble Learning?1.3 Bagging方法 2 随机森林(Random Forest)2.1 随机森林的优点2.2 随机森林算法案例2.3 随机森林的思考(--->提升学习) 3 随机森林(RF&a…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...
uniapp 实现腾讯云IM群文件上传下载功能
UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中,群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS,在uniapp中实现: 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...
