当前位置: 首页 > news >正文

前端对普通数字数组排序示例

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, 910];

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次计算:

  1. (9) [1, 6, 7, 9, 3, 4, 5, 2, 10]

排序.js:14 第2次计算:

  1. (9) [1, 6, 7, 3, 4, 5, 2, 9, 10]

排序.js:14 第3次计算:

  1. (9) [1, 6, 3, 4, 5, 2, 7, 9, 10]

排序.js:14 第4次计算:

  1. (9) [1, 3, 4, 5, 2, 6, 7, 9, 10]

排序.js:14 第5次计算:

  1. (9) [1, 3, 4, 2, 5, 6, 7, 9, 10]

排序.js:14 第6次计算:

  1. (9) [1, 3, 2, 4, 5, 6, 7, 9, 10]

排序.js:14 第7次计算:

  1. (9) [1, 2, 3, 4, 5, 6, 7, 9, 10]

排序.js:14 第8次计算:

  1. (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中&#xff1a;常见问题汇总 1.修改表时提示&#xff1a;不允许修改表结构步骤图例注意 2.将截断字符串或二进制数据。3.在将 varchar 值 null 转换成数据类型 int 时失败。4.插入insert 、更新update、删除drop数据失败&#xff0c;主外键FOREIGN KEY 冲突5.列不允许…...

无线通信中CSI的含义

在无线通信中&#xff0c;CSI代表"Channel State Information"&#xff0c;即信道状态信息。CSI是一种关键的信息&#xff0c;用于评估和描述通信信道的特性&#xff0c;以帮助发送器和接收器在通信过程中做出智能的调整和决策。 CSI包括有关通信信道的以下信息&…...

如何一键核实验证身份证的真伪?

据报道&#xff0c;今年10月10日&#xff0c;广东省佛山市朱某因生活琐事与丈夫发生争吵&#xff0c;民警发现她的身份证有问题。 在民警打算进一步了解情况&#xff0c;查看夫妻二人的身份证件时&#xff0c;朱某的身份证引起了民警的注意。这张身份证表面很光滑&#xff0c;…...

冒泡排序:了解原理与实现

目录 原理 实现 性能分析 结论 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单但效率较低的排序算法。它重复地比较相邻的元素并交换位置&#xff0c;直到整个序列有序为止。虽然冒泡排序的时间复杂度较高&#xff0c;但在小规模数据集上仍然具有一定的实际应用价…...

springboot maven项目环境搭建idea

springboot maven项目环境搭建idea 文章目录 springboot maven项目环境搭建idea用到的软件idea下载和安装java下载和安装maven下载和安装安装maven添加JAVA_HOME路径&#xff0c;增加JRE环境修改conf/settings.xml&#xff0c;请参考以下 项目idea配置打开现有项目run或build打…...

vue3检测是手机还是pc端,监测视图窗口变化

1.超小屏幕&#xff08;手机&#xff09; 768px以下 2.小屏设备&#xff08;平板&#xff09; 768px-992px 3.中等屏幕&#xff08;旧式电脑&#xff09; 992px-1200px 4.大屏设备&#xff08;现代电脑&#xff09; 1200px以上 <script setup name"welcome"> i…...

B - Magical Subsequence (CCPC2021哈尔滨)

思路&#xff1a; &#xff08;1&#xff09;问题&#xff1a;对于已知数组&#xff0c;每组依次选两个&#xff0c;尽量选更多组&#xff0c;选的每组和相等&#xff1b;&#xff08;假定和为x) &#xff08;2&#xff09;于是问题拆分为两步&#xff0c; x是多少x确定时&a…...

Leetcode刷题详解——x的平方根

1. 题目链接&#xff1a;69. x 的平方根 2. 题目描述&#xff1a; 给你一个非负整数 x &#xff0c;计算并返回 x 的 算术平方根 。 由于返回类型是整数&#xff0c;结果只保留 整数部分 &#xff0c;小数部分将被 舍去 。 **注意&#xff1a;**不允许使用任何内置指数函数和…...

windows安装docker,解决require wsl 2问题

想在windows上安装桌面版docker&#xff0c;上官网下载了安装包&#xff0c;安装完后&#xff0c;启动报错&#xff0c;忘了截图了。 大概意思就是require wsl 2。 于是就是docker FAQ中找相关问题解决方案&#xff0c;点&#xff0c;点&#xff0c;点然后就点到微软了。 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&#xff0c;效果如下&#xff0c;上面我们通过 node_exporter 收集的节点状态是 up 状态。 配置 Grafana 访问 http://ip:3000&#xff0c;登录 Grafana&#xff0c;默认的账号密码是 admin:admin&#xff0c;首次登录需要修改…...

面试题:说一下加密后的数据如何进行模糊查询?

文章目录 正文如何对加密后的数据进行模糊查询沙雕做法沙雕一沙雕二 常规做法常规一常规二超神做法 总结 正文 我们知道加密后的数据对模糊查询不是很友好&#xff0c;本篇就针对加密数据模糊查询这个问题来展开讲一讲实现的思路&#xff0c;希望对大家有所启发。 为了数据安…...

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&#xff0c;即Qt Widgets for Technical Applications&#xff0c;其目标是以基于2D方式的窗体部件来显示数据&#xff0c; 数据源以数值&#xff0c;数组或一组浮点数等方式提供&#xff0c; 输出方式可以是Curves&#xff08;曲线&#xff09;&#xff0c;Slider…...

【供应链】仓储、物流、车辆管理

...

从另外一个进程中读取数据

从另外一个进程中读取数据&#xff0c;其实就注入线程&#xff0c;寻址&#xff0c;解析内存&#xff0c;处理数据。例如这个就是从另外一个正在运行的进程中&#xff0c;读取数据并保存。实时性还可以。...

【FPGA零基础学习之旅#17】搭建串口收发与储存双口RAM系统

&#x1f389;欢迎来到FPGA专栏~搭建串口收发与储存双口RAM系统 ☆* o(≧▽≦)o *☆嗨~我是小夏与酒&#x1f379; ✨博客主页&#xff1a;小夏与酒的博客 &#x1f388;该系列文章专栏&#xff1a;FPGA学习之旅 文章作者技术和水平有限&#xff0c;如果文中出现错误&#xff0…...

建立Line类

目录 程序设计 程序分析 系列文章 计算机上的线实际上是线段,要求包含两个端点;颜色为彩虹色;线的粗细是类变量,至少包含show方法。 程序设计 Work5类: package work;import java.util.Scanner;public class Work5 { public static void main(String[] args) {// …...

10_集成学习方法:随机森林、Boosting

文章目录 1 集成学习&#xff08;Ensemble Learning)1.1 集成学习1.2 Why need Ensemble Learning?1.3 Bagging方法 2 随机森林(Random Forest)2.1 随机森林的优点2.2 随机森林算法案例2.3 随机森林的思考&#xff08;--->提升学习&#xff09; 3 随机森林&#xff08;RF&a…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...