问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

js解析常见排序算法

发布网友 发布时间:2024-09-07 10:13

我来回答

1个回答

热心网友 时间:2024-09-07 10:27

冒泡排序基本思想

相信大家也看过在水中的冒泡现象,从下至上,气泡会越来越大,而所谓冒泡排序,也是建立在这个原理上,即从下至上按照一定的顺序,进行排列。

相邻的元素,依次进行对比,如果第一个元素大于第二个元素,那么交换位置。而经过一轮比较之后,最大的元素就会“冒泡”到队尾,之后对已经排好序的元素不予理会,对未排序的元素继续这个步骤,在第n-1(n为数组元素个数)轮之后,完成排序。

代码实现functionbubbleSort(nums){for(leti=0;i<nums.length-1;i++){for(letj=0;j<nums.length-1-i;j++){if(nums[j]>nums[j+1]){lettemp=nums[j]nums[j]=nums[j+1]nums[j+1]=temp}}}returnnums}复杂度

冒泡排序是一种稳定的排序方法,其平均时间复杂度为O(n^2),最好情况的时间复杂度为O(n),最坏情况的时间复杂度为O(n^2),在排序过程当中只需要一个元素的辅助空间,也就是temp,所以空间复杂度为O(1)

例题分析letnums=[3,6,4,2,11,10,5]

第一轮排序:3与6比较之后,不交换,6和4交换位置,之后6再次与2比较,仍然需要进行位置交换,然后继续类似的操作,11就到了末尾,排序之后数组为【3,4,2,6,10,5,11】

第二轮排序:3与4比较不进行位置交换,这个时候我们从上帝视角发现,10为最大元素,那么这个时候10会一直冒泡到11的前一位元素上。结果为【3,2,4,6,5,10,11】

后续操作类似,直到四轮排序结束后,数组变为有序数组

图例如下:

选择排序基本思想

选择排序算法,顾名思义,选择两个字至关重要,首先元素之间进行对比,使用min来记录当前最小元素的下标索引,与首元素交换,也就是排列在数组的起始位置,之后在剩下未排序的数组元素当中又通过这种方式选择出一个最小的元素,在经过n-1轮排序后,数组变为有序数组。

代码实现functionselectionSort(nums){for(leti=0;i<nums.length-1;i++){letmin=ifor(letj=i+1;j<nums.length;j++){if(nums[j]<nums[min])min=j//保存最小值的下标索引}lettemp=nums[i]nums[i]=nums[min]nums[min]=temp}returnnums}复杂度

选择排序是一种不稳定的排序方法,其平均时间复杂度为O(n^2),最好最坏的情况时间复杂度都为O(n^2),在排序过程当中只需要一个元素的辅助空间,所以空间复杂度为O(1)

例题分析letnums=[7,4,5,9,8,2,1]

第一轮排序:第一个元素与其余元素进行比较,找出最小值的下标索引,保存第一个元素的下标为min,之后分别与各个元素进行比较,此时1为最小值,保存min,然后与元素7进行交换,排序完之后为【1,4,5,9,8,2,7】

第二轮排序:元素4与其余未排序元素进行比较,最后与2交换位置,排序之后,数组为【1,2,5,9,8,4,7】

之后依次按照这个方法寻找未排序的最小元素,4轮之后最终变为有序数组

插入排序基本思想

在插入第i个记录时候,R0至R1是有序的,那么将nums[i]与这些元素进行比较,找到应该插入的位置,在插入的位置之后的元素都需要依次向后移动

默认第一个元素是存在顺序的,那么从第二个元素开始,需要依次进行比较,将该元素从后往前开始比较,如果比当前元素大,那么将该元素后移,直到找到一个比该元素更小的元素,然后将该元素放在当前元素后面。如此反复,即可排序成功

代码实现functioninsertionSort(nums){for(leti=1;i<nums.length;i++){for(letj=i;j>0;j--){if(nums[j]<nums[j-1]){lettemp=nums[j];nums[j]=nums[j-1];nums[j-1]=nums;}}}returnnums;}

这么一瞅,是不是有点像冒泡排序

还有第二种,但是第二层循环我用了var关键字来声明,因为let块级作用域的原因,nums[j+1]=temp这一行代码会访问不到变量j,所以我用var来声明,但是无伤大雅,这里也可以用while循环来做的,网友们可自行琢磨

functioncharu(nums){for(leti=1;i<nums.length;i++){if(nums[i]<nums[i-1]){lettemp=nums[i]//保存nums[i]nums[i]=nums[i-1]for(varj=i-1;j>=0&&nums[j]>temp;j--)nums[j+1]=nums[j]nums[j+1]=temp}}returnnums;}复杂度

插入排序是一种稳定的排序方法,其平均时间复杂度为O(n^2),最好情况的时间复杂度为O(n),最坏情况的时间复杂度为O(n^2),在排序过程当中只需要一个元素的辅助空间,所以空间复杂度为O(1)

例题分析letnums=[5,7,4,6,3,1,2,9,8]

默认第一个元素5是有序的,那么从第二个元素开始,5会先与7比较,此时按兵不动,而后比较4会插入5的前面,依次类推,就可以得到有序数组

希尔排序基本思想

希尔排序又被称为“缩小增量排序”,这是对插入排序算法的改进

首先将整个待排序序列分为若干子序列,然后分别进行直接插入排序,待整个序列中的记录基本有序时,再对全体序列进行一次插入排序

先取一个小于n的整数d1作为第一个增量,将数组分为d1个组,即所有距离为d1倍数序号的记录放在同一个组当中,在各组当中进行插入排序。

然后取d2(d2<d1)重复上述分组和排序工作

直到所取的增量为di=1,所有记录都在同一组然后进行插入序列为止一般取的都是d1=n/2?d2=2/d1,依次类推

代码实现functionshellSort(nums){lethalf=parseInt(nums.length/2);//设置增量为原数组长度的一半for(letgap=half;gap>=1;gap=parseInt(gap/2)){for(leti=gap;i<nums.length;i++){for(letj=i-gap;j>=0;j=j-gap){if(nums[j]>nums[j+gap]){lettemp=nums[j];nums[j]=nums[j+gap];nums[j+gap]=temp;}}}}returnnums}复杂度

希尔排序也是一种不稳定的排序方法,其平均时间复杂度约为O(nlogn^2),约为O(n^1.3),最好情况的时间复杂度为O(n),最坏情况的时间复杂度为O(n^2),在排序过程当中只需要一个元素的辅助空间,所以空间复杂度为O(1)

例题分析

因为这里数量太少不利于讲解,我换个例子

letnums=[9,1,2,5,7,4,8,6,3,5]

我们就取d1=5(n/2)、d2=3(d1/2)、d3=2(d2/2),d4=1来作为排序的增量,依据情况而定上下取整

第一轮排序:按照d1=5,进行分组,那么9和4为一组,1和28,2和6,5和3,7和5两两配对,那么此时就需要比较元素之间的大小,各组之间进行插入排序,那么第一轮排序后,数组为【4,1,2,3,5,9,8,6,5,7】

第二轮排序:按照d2=3,进行分组,那么4、3、8、7为一组,1、5、6以及2、9、5各成一组,插入排序后,数组为【3,1,2,4,5,5,7,6,9,8】

第三轮排序:按照d3=2,j进行分组,也就是相邻元素不为一组,3,2,5,7,9为一组,1,4,5,6,8为一组,那么两组内部进行插入排序后,数组为【2,1,3,4,5,5,7,6,9,8】

第四轮排序:直接取d4=1,全部序列进行插入排序,得到最后的结果【1,2,3,4,5,5,6,7,8,9】

其实实际当中不用四轮,三轮即可,只要向下取整就好。

快速排序基本思想

通过一趟排序将待排序的元素划分为独立的两个部分,称为前半区和后半区,其中前半区的元素都不大于后半区元素,然后再分别对这两部分进行快速排序,从而使整个序列有序

附设两个指针变量i和j,分别指向序列第一个元素和最后一个元素,设第一个关键字为pivot,从j的位置向前检索找到第一个小于pivot的元素,将该元素向前移动到i指示的位置,从i所指的位置向后搜索,找到第一个大于pivot的元素将该元素移动到j所指的位置,重复过程直到i、j相遇

代码实现functionPartition(nums,low,high){vari=low,j=high,pivot=nums[i];while(i<j){//从右往左找while(i<j&&nums[j]>pivot)j--;if(i<j){swap(i++,j,nums);}//从左往右找while(i<j&&nums[i]<=pivot)i++;if(i<j){swap(i,j--,nums);}}returni;//返回基准元素位置}functionswap(a,b,nums){console.log(a,b,nums[a],nums[b])vartemp=nums[a];nums[a]=nums[b];nums[b]=temp;}functionQuickSort(nums,low,high){varmid;if(low<high){mid=Partition(nums,low,high);//返回基准元素位置QuickSort(nums,low,mid-1);//左边快速排序QuickSort(nums,mid+1,high);//右边快速排序}}QuickSort(nums,0,nums.length-1);复杂度

快速排序是一种不稳定的排序方法,其平均时间复杂度为O(nlog2n),最好情况的时间复杂度为O(nlog2n),最坏情况的时间复杂度为O(n^2),空间复杂度为O(nlog2n)

例题分析

我从网上找了个例子,相信大家更容易看懂,哈哈哈

重点就是对双指针解法的理解程度,需要在j指针找到比i指针更小的元素,进行替换

归并排序基本思想

归并其实利用的是一个递归的思想,将长度为n的整个数组看成是n个长度为1的多个数组,对这些数组进行两两归并,得到n/2个长度为2或者1的有序数组,之后再两两归并,重复这个步骤,直到所有的元素都形成长度为n的数组。

大致步骤如下:

把n个记录看成n个长度为l的有序子表

进行两两归并使记录关键字有序,得到n/2个长度为2的有序子表

重复第2步直到所有记录归并成一个长度为n的有序表为止。

具体操作为不断切割数组,类似于对半切,不断的在中间元素切割,使得各个数组一分为二,最终变为n个长度为1的数组,之后再两两合并这些元素,形成一个有序链表。

代码实现letnums=[3,6,4,2,11,10,5]0复杂度

归并排序是一种稳定的排序方法,其平均时间复杂度为O(n^2),最好情况的时间复杂度为O(nlog2n),最坏情况的时间复杂度为O(nlog2n),在排序过程当中只需要n个元素的辅助空间,所以空间复杂度为O(nlogn)

例题分析

大致步骤如下:

堆排序基本思想

若将序列对应的一维数组看成是一个完全二叉数?,完全二叉树中所有非终端节点的值均不小于(或者不大于)其左右孩子节点的值,因此在一个堆中,堆顶元素,即完全二叉树的根节点必然为序列中的最大元素或者是最小元素,并且堆中的任一一棵子树也都是堆,若堆顶为最小元素,则称为小根堆落;堆顶为最大元素,则称为大根堆。

对一组待排序记录的元素首先按堆的定义排成一个序列,即建立初始堆,从而可以输出堆顶的最大元素(对于大根堆而言),?然后将剩余的元素再调整成新堆,便得到次大的元素,如此反复,直到全部元素排成有序序列为止?

写代码前,需要知道这些基本知识

Parent(i)=floor((i-1)/2),i的父节点下标

Left(i)=2i+1,i的左子节点下标

Right(i)=2(i+1),i的右子节点下标

代码实现letnums=[3,6,4,2,11,10,5]1复杂度

堆排序是一种不稳定的排序方法,其平均时间复杂度为O(nlog2n),最好情况的时间复杂度为O(nlog2n),最坏情况的时间复杂度为O(nlog2n),在排序过程当中只需要一个元素的辅助空间,所以空间复杂度为O(1)

例题分析

这里我也是偷个懒,我感觉说的可能不明白,让读者们看图说话吧!

原文:https://juejin.cn/post/7096029648026337287
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
云南省昭通昭阳区邮政编码 圆通快递能送到云南昭阳区昭通市盘河镇吗? 京山好玩的宾馆在哪里? 湖北咸宁温泉爱尚网吧在哪里啊 求剑网三《剑啸江湖》歌曲下载,邮箱是:rizhun@qq.com 诛仙在哪里挂散仙啊?我129魔怀光白坤装可以去挂吗?怎么设置捡散仙的... 昂科雷电脑板故障(昂科雷变速箱电脑板故障) 诛仙前传魔怀光的法宝是用噬魂好,还是天邪好? ...加湿器什么牌子好?无雾加湿器有必要买吗?筛选出了这10款加湿器... 全民飞机大战中K18满级和嫦娥满级谁厉害? 精彩表现展现了什么 仙人球腐烂怎么办,我家烂了好多了,我妈妈把烂的地方全刮下,然后怎么办... 销售砂石料注册什么公司 苯丙涂料是聚胺脂吗 2017十大品牌沙发排名 高等学校教材·计算机网络技术基础教程内容简介 齐心文具如何在全球范围内建立并维护其营销网络? 合肥一睿家居用品有限公司怎么样? 快手视频下载到本地 ...但在释放过后就会很虚弱。可以用一个四字成语来形容吗? ...身体虚弱,经常生病)把括号里的句子换成四字成语 毒属性魂师能不能让自己中毒? 销售非法出版物会收到什么处罚? 最近迷上了igo平衡车,有看到坐立两用,请问是什么意思? 境外特种设备进口中国 初一发育得这么好宝宝知道 我妹妹12岁,这个又不用穿胸罩宝宝知道 抽烟加个过滤嘴有用吗 违章在12123几天可以查到? 我儿子打呼噜很严重 怎么办呢? 精彩出彩,有什么区别!? js两种数据类型(javascript中的数据类型分为两大类) 华为手机怎么进入安全模式,如何退出? 南昌市城市出租汽车管理条例第一章 总则 南昌市环保监理所职能法律依据 从南昌大桥到南昌市物价局怎么坐车 谈我最喜欢的电视剧《跨过鸭绿江》,观后感 电脑开机黑屏键盘指示灯不亮怎么回事 甄嬛传最后一集,皇上快死的时候,甄嬛说:那年杏花微雨 你说的。 什么意... 跨过鸭绿江观后感企业纪检人员心得 《精忠报国》歌词"我愿守土复开疆"是否含有侵略 ...不亮 独显 cpu散热 电源 机械硬盘都转 键盘灯不亮 精忠报国,创作时期的原唱是谁?(网上说是20世纪30年代那个时候)有他唱的... 电脑开机没显示键盘灯不亮是什么原因? 老人财产被骗,银行未充分提示风险是否需要担责 “RER”指代的是“静止能量率”吗? 电脑开机黑屏,鼠标键盘灯不亮,是什么原因。 老人被诈骗,在银行成功汇款,银行有责任吗 aelkbuqx kysxprer请问这两组字母是什么意思 野外烧烤有什么需要注意的