前端对普通数字数组排序示例
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…...
避坑指南:Vue2中xlsx-style设置行高无效?手把手教你修改源码并封装通用导出函数
Vue2中xlsx-style行高设置失效的深度解决方案与工程化封装 在Vue2项目中处理Excel导出时,很多开发者会遇到一个令人困惑的问题:明明按照xlsx-style的文档设置了row.hpx属性,导出的Excel文件却依然保持默认行高。这背后其实隐藏着xlsx.js源码中…...
基于西门子1200PLC的六层电梯控制系统设计,含PLC程序和HMI仿真工程,适用于博途V14...
基于西门子1200PLC的六层电梯控制系统设计,含PLC程序和HMI仿真工程,适用于博途V14及以上版本 附赠IO点表、PLC接线图、主电路图和控制流程图 提供服务,确保正常运行电梯控制系统总被当作PLC入门经典案例,但真要在博途环境里实现六…...
手把手教你用NLI-DistilRoBERTa-Base:快速搭建自然语言推理服务
手把手教你用NLI-DistilRoBERTa-Base:快速搭建自然语言推理服务 1. 引言:什么是自然语言推理(NLI) 自然语言推理(Natural Language Inference)是NLP领域的一项重要任务,它需要判断两个句子之间的关系。想象一下,当你在阅读一段文…...
Bloaty二进制大小分析器:10个常见问题解决技巧
Bloaty二进制大小分析器:10个常见问题解决技巧 【免费下载链接】bloaty Bloaty: a size profiler for binaries 项目地址: https://gitcode.com/gh_mirrors/bl/bloaty Bloaty是一款强大的二进制大小分析工具,能够帮助开发者深入了解二进制文件的大…...
OmX与边缘计算:打造高效边缘设备的AI助手完整指南
OmX与边缘计算:打造高效边缘设备的AI助手完整指南 【免费下载链接】oh-my-codex OmX - Oh My codeX: Your codex is not alone. Add hooks, agent teams, HUDs, and so much more. 项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-codex OmX&#x…...
Nunchaku FLUX.1 CustomV3实战教程:多LoRA并行加载与动态权重切换操作指南
Nunchaku FLUX.1 CustomV3实战教程:多LoRA并行加载与动态权重切换操作指南 1. 认识Nunchaku FLUX.1 CustomV3 Nunchaku FLUX.1 CustomV3是一个基于Nunchaku FLUX.1-dev模型的文生图工作流程,通过整合FLUX.1-Turbo-Alpha和Ghibsky Illustration两个LoRA…...
内网渗透零基础入门教程!小白也能轻松搞懂内网渗透基础知识点
内网渗透初探 | 小白简单学习内网渗透 0x01 基础知识 内网渗透,从字面上理解便是对目标服务器所在内网进行渗透并最终获取域控权限的一种渗透。内网渗透的前提需要获取一个Webshell,可以是低权限的Webshell,因为可以通过提权获取高权限。 …...
**管线流程**:模型矩阵 × 视图矩阵 × 投影矩阵 × 顶点 → GPU自动完成裁剪/光栅化
一、二进制、八进制、十六进制的转换方法(通俗版) 本质:都是“逢几进一”的计数法,只是“底数”不同(2/8/16)。 二进制(Base-2):只用 0 和 1,是计算机硬件唯一…...
STM32开发方式对比与HAL库深度解析
1. STM32开发方式概述对于刚接触STM32的开发者来说,选择合适的开发方式是首要问题。目前主要有三种开发方式:直接操作寄存器、使用标准库(Standard Peripheral Library)和使用HAL库(Hardware Abstraction Layer&#x…...
实战指南:用Python的pyttsx3库打造你的专属语音助手
1. 从零认识pyttsx3:你的代码会说话 第一次听到电脑用标准播音腔朗读出我写的文字时,那种感觉就像小时候收到会说话的生日贺卡。pyttsx3这个神奇的Python库,能让任何文本通过声卡变成人声。不同于需要联网的语音合成服务,它完全离…...
