js-常见排序算法

article/2025/11/9 20:32:57

目录

一、选择排序

二、冒泡排序

 

三、插入排序

 1. 希尔排序

四、归并排序

五、快速排序


版权声明:本文为博主原创文章,若文章中有错误请联系博主改正,请不要恶意留言(不喜欢请绕道)。欢迎大家转载,转载时请注明原文地址:https://blog.csdn.net/qq_37674616/article/details/82315651

目录

一、选择排序

二、冒泡排序

三、插入排序

 1. 希尔排序

四、快速排序


我们衡量一个算法的指标包括:

  • 时间复杂度 (在排序过程中需要比较和交换的次数)

  • 空间复杂度 (在排序过程中需要的辅助存储空间)

  • 稳定性 (该算法的实现是否可以保证排序后相等元素的初始顺序,只要该算法存在一种实现可以保证这种特征,那么该算法就是稳定的)

  • 内部排序/外部排序 (在排序过程中数据元素是否完全在内存)

下表为各排序算法的性能标准:

一、选择排序

工作原理:初始时在未排序序列中找最小(最大)元素,放到序列的起始位置作为已排序序列;然后再从剩余未排序元素中继续寻找最小(大)元素,放到已排序序列的末尾。以此类推。知道所有元素均排序完毕。
        

        /*** @Author   cc* @DateTime 2018-09-01* @param    {arr} 未排序数组* @return   {arr} 已排序数组* @description 选择排序*/function sort(arr){var len=arr.length;//已排序序列的末尾for(var i=0;i<len;i++){var min=i;//待排序序列for(var j=i+1;j<len;j++){//从待排序序列中找到最小值if(arr[j]<arr[min]){min=j;}}if(min!=i){var temp=arr[i];arr[i]=arr[min];arr[min]=temp;}}return arr;}//测试var arr=[1,4,35,3,2];sort(arr);console.log(arr); //[1,2,3,4,35]
/*** @Author   cc* @DateTime 2020-05-07* @param    {nums} 未排序数组* @return   {nums} 已排序数组* @description 选择排序*/
function insertionSort (nums) {for(let i=1;i<nums.length;i++){for(let j=0;j<i;j++){snapshot(nums)if(nums[i]<nums[j]){let temped=nums.splice(i,1);nums.splice(j,0,temped[0])}}}
}


        该排序算法不稳定,最差时间复杂度  o(n^2);最优时间复杂度  o(n^2);平均时间复杂度  o(n^2)

二、冒泡排序

冒泡排序是一种简单的排序算法,它重复走访要排序的数列,一次比较两个元素,如果他们的的顺序错误就把他们调换过来,知道没有元素再需要交换,排序完成。
           算法描述如下:   

比较相邻的元素。如果第一个比第二个大,就交换他们;
           对于每个相邻的元素重复相同的工作,知道最后一个元素,这样最后的元素会是最大的数
           针对所有元素重复以上的步骤,除了最后一个元素
           重复上面1~3步骤,知道排序结束

算法实现:

     /*** @Author   cc* @DateTime 2018-08-31* @param    {arr} 待数组* @return   {arr} 排好序的数组* @description 这是一个冒泡排序算法*/function bubbleSort(arr) {var len = arr.length;for (var i = 0; i < len - 1; i++) { //比较的趟数,每次将最大值放到数组最后for (var j = 0; j < len - i - 1; j++) { //将相邻的两个元素,两两比较if (arr[j]>arr[j+1]) { //元素交换值var temp=arr[j];arr[j]=arr[j+1];arr[j+1]=temp;}}}return arr;}var arr=[1,3,5,12,14,8,99];var result=bubbleSort(arr);console.log(result); //[1, 3, 5, 8, 12, 14, 99]

辅助草图:


        冒泡排序是稳定的排序算法,它的最差时间复杂度 o(n^2)即已排序数组;平均时间复杂度o(n^2),最优时间复杂度o(n)即在内部循环第一次运行时,使用一个旗标来表示该数组是不是已经是最小的了。
          

 将上面代码做如下改动
 

/*** @Author   cc* @DateTime 2020-05-07* @param    {nums} 未排序数组* @return   {nums} 已排序数组* @description 冒泡排序*/
function bubbleSort(nums) {do {var swapped = false;    for (var i = 0; i < nums.length; i++) {if (nums[i] > nums[i+1]) {var temp = nums[i];nums[i] = nums[i+1];nums[i+1] = temp;swapped = true;}}} while(swapped); 
}

草图如下所示:

 

三、插入排序


         工作原理:是通过构建有序序列,对未排序数组,在已排序序列中从后向前扫描,找到相应位置并插入。
         算法描述:
             1. 从第一元素开始,该元素可以默认已经被排序
             2. 取出下一个元素,在已经排序序列中从后向前扫描
             3. 如果已排序的元素大于新元素,将该元素移到下一个位置
             4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
             5.将新元素插入到该位置
             6.重复2~5

                     /*** @Author   cc* @DateTime 2018-09-01* @param    {arr} 待排序序列* @return   {arr}  排好序序列* @description 插入排序*/function insertSort(arr) {var len = arr.length;var preIndex, current;for (var i = 1; i < len; i++) {preIndex = i - 1; //排好序的数组最后一个下标current = arr[i]; //待排序的数值//让待排序的值与排序好的数组值进行比较while (preIndex >= 0 && arr[preIndex] > current) {arr[preIndex + 1] = arr[preIndex];preIndex--;}//待排序的数值大于等于排序好的值arr[preIndex + 1] = current;}return arr;}var arr=[8, 3, 5, 9, , 7, 1, 2 ];var result=insertSort(arr); //从小到大排序console.log(result); //[1, 2, 3, 4, 5, 6, 7, 8]


                插入排序稳定,最差时间复杂度o(n^2)待排序列是降序序列;最优时间复杂度o(n)即待排序列是升序
                平均时间复杂度o(n^2)

 1. 希尔排序


            希尔排序:    是对插入排序的改进,它与插入不同之处它会优先比较距离较远的元素
            算法描述:
                 选择一个增量序列 t1,t2,...tk,其中ti>tj,tk=1;
                 按增量序列个数k,对序列进行k趟排序
                 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m的子序列,分别对各自表进行直接插入排序.当增量因子为一时,整个序列被分为一组,算法终止。

                     /*** @Author   cc* @DateTime 2018-09-01* @param    {arr}* @return   {arr} 已排序数组* @description 希尔排序*/function ShellSort(arr) {var len = arr.length;var temp, gap = 1;while (gap <= len / 3) {gap = gap * 3 + 1;  //生成增量}while (gap >= 1) {  //当分组变成成1时则排序完成for (var i = gap; i < len; i++) {  //按增量循环数组temp = arr[i];//增量大于零且前面的数组的值大于后面数组的值则交换位置for (var j = i - gap; j >= 0 && arr[j] > temp; j -= gap) {arr[j + gap] = arr[j];}arr[j + gap] = temp;}console.log(gap);gap = (gap - 1) / 3; //递减增量}return arr;}var arr = [5, 9, 2, 4,1,2,8,3,9,1];var result = ShellSort(arr);console.log(result);

  下图为增量为4时的内部数据交换图:

             

希尔排序稳定,时间复杂度为o(n^2),最优时间复杂度o(n)

四、归并排序

算法描述:

  指的是将两个已经排序的序列合并成一个序列的操作。归并排序算法依赖归并操作。

算法思想: 

 采用分支法,递归地把当前序列平均分割成两半,然后再保证左右顺序情况下合并在一起。

 

/*** @Author   cc* @DateTime 2020-05-07* @param    {nums} 未排序数组* @return   {nums} 已排序数组* @description 归并排序*/
function mergeSort(nums){if(nums.length<2) return nums;const middle=Math.floor(nums.length/2);const left=nums.slice(0,middle);const right=nums.slice(middle);return merge(mergeSort(left),mergeSort(right))
}const merge=(left,right)=>{const result=[]while(left.length&&right.length){if(left[0]>right[0]){result.push(right.shift())}else{result.push(left.shift())}}return result.concat(left,right);}

五、快速排序


        该方法的基本思想:
            1. 从数列中取出一个数作为基数。
            2. 重新排序数列,所有元素比基准值小的放到基准值前,所有元素比基准值大的放到其后。
            3. 在对基准值左右区间,重复第二步,直到个区间只有一个数
        算法实现:

            /*** @Author   cc* @DateTime 2018-09-02* @param      arr   待排序数组* @param      left  数组第一个元素下标(0)* @param      right 数组最后一个元素下标* @return     arr   排好序的数组*/function quickSort(arr,left,right){if(left<right){var i=left,j=right;var x=arr[left]; //将基准数保存到 x 中while (i<j) {// 从右边向左边找小于x的数while(i<j && arr[j]>=x){j--;}if(i<j){arr[i]=arr[j];i++;}//从左边向右边找大于x的数while(i<j && arr[i]< x){i++;}if(i<j){arr[j]=arr[i];j--;}}arr[i]=x;console.log('i',i);console.log(x);console.log(arr);quickSort(arr,left,i-1);quickSort(arr,i+1,right);}return arr;}var arr=[3,2,45,12,4,3,12,4];console.log("原数组",arr);quickSort(arr,0,arr.length-1);console.log(arr); //[2, 3, 3, 4, 4, 12, 12, 45]

下图为上面算的内部数据描述:

 

/*** @Author   cc* @DateTime 2020-05-08* @param    {nums} 未排序数组* @return   {nums} 已排序数组* @description 快速排序*/function quickSort(nums){if(nums.length<2) return nums;const pivot=nums[nums.length-1];const left=[];const right=[];for(let i=0;i<nums.length-1;i++){if(nums[i]<pivot){left.push(nums[i])}else{right.push(nums[i])}}return [...quickSort(left),povit,...quickSort(right)]
}

 


http://chatgpt.dhexx.cn/article/MUCWt7qY.shtml

相关文章

3.JS排序算法之选择排序

选择排序&#xff08;selectSort&#xff09;&#xff0c;顾名思义&#xff0c;每次选择最值进行排序 目录 一、选择排序算法原理 二、选择排序算法分析 三、选择排序算法应用实例 四、选择排序的适用场景 一、选择排序算法原理 1.思路 选择排序的实现思路是从未排序序列中…

JavaScript实现十大排序算法(图文详解)

冒泡排序 排序的效果图 解法 当前解法为升序 冒泡排序的特点&#xff0c;是一个个数进行处理。第i个数&#xff0c;需要与后续的len-i-1个数进行逐个比较。 为什么是 len-i-1个数&#xff1f; 因为数组末尾的i个数&#xff0c;已经是排好序的&#xff0c;确认位置不变的了。…

JS 常见的排序算法

工作中算法不常用&#xff0c;但是排序经常用。因此在这里整理了几种JS中常见的排序算法。 冒泡排序 1、算法思想&#xff1a;判断两个相邻元素&#xff0c;大于则交换位置 2、算法步骤 从数组中第一个数开始&#xff0c;依次与下一个数比较并次交换比自己小的数&#xff0c…

详细解析十大排序算法(js实现)

详细解析十大排序算法js实现 算法概述1.冒泡排序1.1算法描述1.2动图演示1.3代码实现 2.选择排序2.1算法描述2.2动图演示2.3代码实现2.4算法分析 3.插入排序3.1算法描述3.2动图演示3.3代码实现3.4算法分析 4.希尔排序4.1算法描述4.2动图演示4.3代码实现4.4算法分析 5.归并排序5.…

Excel中使用SUMIFS公式时计算结果不正确(原因:有超过15位数字的长编码)

在使用SUMIFS公式进行多条件求和时发现求和结果部分正确&#xff0c;部分错误。 常见原因&#xff1a; 1、公式错误 2、数据格式有问题或者有空格等 仔细检查后发现并不是上述两个原因&#xff0c;而是求和的公式中涉及到超过15位数字的长编码。常见的SUMIF、SUMIFS、COUNTIF等…

mybatis-plus使用

1 mybaitsplus简介 &#xff08;1&#xff09;对于mybatis功能的增强&#xff0c;具体的体现就是对于单表的操作都生成好了&#xff0c;分页&#xff0c;条件查询使用很方便&#xff0c;例如查询操作&#xff0c;直接使用wrapper的实现类&#xff0c;调用方法进行条件的增加&a…

四、Hibernate框架的API (三)-- Session对象

一、Session对象 1.Hibernate最重要的对象,只用使用hibernate与数据库操作&#xff0c;都用到这个对象2.该对象维护了一个Connection对象。代表了与数据库连接的会话。3.该对象实质上是对Connection对象的包装&#xff0c;在Connection对象基础之上&#xff0c;封装了一些方法。…

Criteria的用法

一、Hibernate提供了5种检索对象的方式 1.导航对象图检索方式&#xff1a;根据已经加载的对象导航到其他对象    from Emp e group by e.dept.deptName 2.OID检索方式&#xff1a;按照对象的OID来检索对象   get/load 3.HQL检索方式&#xff1a;使用面向对象的HQL查询语…

第13章:处理Excel电子表格(笔记)

13.1&#xff1a;Excel文档 13.2&#xff1a;安装openpyxl模块 pip install --user --Uopenpuxl2.6.2 这是安装2.6.2版本的&#xff0c;比较新的版本与学习的书籍的信息有一点不兼容 13.3&#xff1a;读取Excel文档 13.3.1&#xff1a;用openpyxl模块打开Excel文档 import …

关于 range.autofilter 和 VBA的 filter

1 range().autofilter容易出错的地方 1.1 range().autofilter的返回值 range().autofilter 返回值总是 true返回值并不是对象&#xff0c;而是执行一个筛选的操作所以 Sub test1_filter5() Dim rng1 As Range Set rng1 Range("b1:b20").AutoFilter(field:1, Crit…

Opencv学习之角点检测

Opencv学习之角点检测 角点检测 在图像处理和计算机视觉领域&#xff0c;兴趣点&#xff08;interest points&#xff09;&#xff0c;也被称作关键点&#xff08;key points&#xff09;、特征点&#xff08;feture points&#xff09;。它被大量用于解决物体识别、图像识别…

VBA-Range.AutoFilter 方法浅析

VBA-Range.AutoFilter 方法的一些“坑” 学到筛选的时候遇到一些小小的“坑”&#xff0c;记录下。 录制出来的宏是这样的&#xff0c; Sub 宏1()宏1 宏Rows("1:1").SelectSelection.AutoFilterActiveSheet.Range("$A$1:$F$1048").AutoFilter field:4, …

Hibernate查询Query By Criterial

提供的检索方式&#xff1a;&#xff08;1&#xff09;导航对象图检索方式 &#xff08;2&#xff09;OID检索方式&#xff08;3&#xff09;HQL检索方式&#xff08;4&#xff09;QBC检索方式[query by Criteria(标准)]&#xff08;5&#xff09;本地SQL检索方式 1、简介 1.…

SLUB和SLAB的区别

转载&#xff1a;http://www.cnblogs.com/tolimit/ 首先为什么要说slub分配器&#xff0c;内核里小内存分配一共有三种&#xff0c;SLAB/SLUB/SLOB&#xff0c;slub分配器是slab分配器的进化版&#xff0c;而slob是一种精简的小内存分配算法&#xff0c;主要用于嵌入式系统。慢…

[linux kernel]slub内存管理分析(7) MEMCG的影响与绕过

文章目录 背景前情回顾描述方法约定 MEMCG总览省流总结简介 slub 相关 memcg机制kernel 5.9 版本之前结构体初始化具体实现 kernel 5.9-5.14kernel 5.14 之后 突破slab限制方法cross cache attackpage 堆风水 总结 背景 前情回顾 关于slab几个结构体的关系和初始化和内存分配…

linux slub分配器,Vi Linux内存 之 Slub分配器(六)

再来看内置式对象&#xff0c;如下图所示。指针位于对象的头部&#xff0c;与对象共用存储空间。这是因为对象被分配出去之前&#xff0c;其存储空间是空闲的可用状态&#xff0c;可用于存放空闲对象指针。对象被分配出去后&#xff0c;也不再需要这个指针了&#xff0c;可以被…

一文给你解决linux内存源码分析- SLUB分配器概述(超详细)

SLUB和SLAB的区别 首先为什么要说slub分配器&#xff0c;内核里小内存分配一共有三种&#xff0c;SLAB/SLUB/SLOB&#xff0c;slub分配器是slab分配器的进化版&#xff0c;而slob是一种精简的小内存分配算法&#xff0c;主要用于嵌入式系统。慢慢的slab分配器或许会被slub取代&…

Linux内存管理(2):SLAB/SLUB系统(基于线性映射)

一、概述 伙伴系统最大限度地解决了内存管理地外碎片问题,但是对于内碎片问题却无能为力。但内核实际使用内存的时候,却大多是小于一个页的单位。为了解决内核自身使用小块内存的碎片问题,Linux引入了基于对象的内存管理(或者叫内存区管理,Memory Area Management),就是SL…

slub分配器学习系列之linux5.10

前言 前一篇文章对 linux5.10 的 slab 分配器底层实现进行了探究与学习。进一步地&#xff0c;本篇文章将对 linux5.10 的 slub 分配器进行探究&#xff0c;对比看看两者的实现有何不同&#xff0c;做了哪些"必要的"改进。 slub 分配器 关于 slub 分配器的基本原理…

linux内核虚拟内存之slub分配器

上一章主要讲述以页为最小单位进行内存分配的伙伴管理算法&#xff0c;较大程度上避免了内存碎片问题。而实际上对内存的申请却不是每次都申请一个页面的&#xff08;比如文件节点&#xff0c;任务描述符等结构体内存&#xff09;&#xff0c;通常是远小于一个内存页面的大小&a…