分享好友 最新动态首页 最新动态分类 切换频道
十大经典排序算法:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、计数排序、基数排序、桶排序
2024-12-26 13:16

排序所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。

稳定性假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次 序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排 序算法是稳定的;否则称为不稳定的。

内部排序数据元素全部放在内存中的排序。

外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不断地在内外存之间移动数据的排序。



基本思想

直接插入排序是一种简单的插入排序法,其基本思想是:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。

实际中我们玩扑克牌时,就用了插入排序的思想

我们来看一下动图

如何用代码实现这个排序呢,我们观察动图可以看到假如0-end有序那么end+1挨个与0-end的值比较,如果比end+1大就像右移动一位然后继续下一个数比较,如果比end+1小则就插入到end的前面,以此内推

代码如下

 
 

直接插入排序的特性总结

1. 元素集合越接近有序,直接插入排序算法的时间效率越高

2. 时间复杂度:O(N^2),什么情况最坏:逆序,最好:顺序有序:O(N)

3. 空间复杂度:O(1),它是一种稳定的排序算法

4. 稳定性:稳定


希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成个 组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工 作。当到达gap=1时,所有记录在统一组内排好序。

希尔排序分为两个步骤

        1. 预排序(让数组接近有序

        2. 插入排序

什么是预排序,预排序就是把数据分为gap个组,gap是几就是几组,假如gap为3那就是分3组,间隔为3的就是一组数据,然后分别对每组数据进行预排序。如下图

我们以红色这组为例来对这组数据进行预排序。

代码如下

我们的希尔排序用到了插入排序的思想

这里的结束条件为什么不是n-1而是n-gap呢,因为当我们排最后一组数据的时候i的位置位于8而tmp是5,如果结束条件是i<n-1就会越界,绿色和紫色那组也是一样的。

然后我们把每组都进行预排序,可以分开写也可以合并写。

一组一组进行预排序

多组并着走

预排序的目的是让数组接近有序,而不是真正的有序,如果是逆序的情况我们通过预排序就可以很快的把较大的数放到后面,因为我们一次移动gap个数,如果不进行预排序就需要一次一次的移动,使用预排序效率会有提升。 

什么是希尔排序呢,希尔排序就是进多组预排序,当gap==1就是插入排序,我们先进行预排序,预排序排好后就已经快接近有序了,最后进行插入排序就可以了。

那么我们的gap应该给多少合适呢

gap越大,大的可以越快跳到后面,小的数可以越快跳到前面,越不接近有序

gap越小,跳得越慢,但是越接近有序,当gap==1相当于插入排序就有序了

代码如下

 

这里gap每次缩小三倍是比较高效的+1是为了防止gap==0的情况没法进行最后一次的插入排序。

下面是一些对于gap=gap/3+1的解释说明

《数据结构-用面相对象方法与C++描述》--- 殷人昆

希尔排序的特性总结

1. 希尔排序是对直接插入排序的优化。

2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就 会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。

3. 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的 希尔排序的时间复杂度都不固定

《数据结构(C语言版)》--- 严蔚敏

4. 稳定性:不稳定

我们可以简单的分析一下它大概的时间复杂度

gap组数据,假设忽略掉+1(方便计算),每组数据个数 = n/gap,gap = n / 3

1.gap = n/3,每组3个数据,最坏情况下,第一趟预排序的消耗:(1+2)*n/3,即n(每组比较次数*组数

2.gap = n / 9,每组9个数据,最坏情况下,第二趟预排序的消耗:(1+2+3+...+8)*n/9,即4*n

...

3.最后一趟(已经很接近有序了),gap==1,就是直接插入排序消耗:n

大概的消耗如图所示,我们可以记住希尔排序的时间复杂度大概是O(N^1.3)左右


每一次从待排序的数据元素中选出最小和最大的元素,将最小的与开头元素进行交换,最大的与最后面的元素进行交换,两边指针分别进行减减和加加,直到两个指针相等。

 

选择排序的特性总结

1. 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用

2. 时间复杂度:O(N^2)

3. 空间复杂度:O(1)

4. 稳定性:不稳定 


堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是 通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆。

 

 直接选择排序的特性总结

1. 堆排序使用堆来选数,效率就高了很多。

2. 时间复杂度:O(N*logN)

3. 空间复杂度:O(1)

4. 稳定性:不稳定

更多详情点击:【数据结构】堆的实现和堆排序--TOP-K问题-CSDN博客


基本思想:所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排 序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。

冒泡排序的思想:两两相邻的元素进行比较,如果不满足顺序就交换,满足顺序就找下一对。

 

冒泡排序的特性总结

1. 冒泡排序是一种非常容易理解的排序

2. 时间复杂度:O(N^2)

3. 空间复杂度:O(1)

4. 稳定性:稳定 


快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中 的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右 子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

我们先来看看快排的动图

整体的思想就是左边的数据做key,然后让right先走遇到比key小的就停下来,然后left走当left遇到比key大的值就停下来然后与right的值进行交换,当left和right相遇的时候就让key的值和left交换,在把key赋值成相遇 位置的值,这是单趟排序,然后以key为中心分成两个区间,进行不递归的递归直到最后的区间只有一个值,或许不存在区间,递归开始返回。

代码如下: 

 

如果我们想让快排的效率高就要考虑一些极端的情况,比如在有序的情况下右边一直没找到比key小的值他们直接在key的位置相遇了,这样不就变成一个等差数列了大大降低快排的效率,如果让key作为一个中间值那么效率才快,所以我们可以定义一个三数取中函数,函数的返回值作为key。

三数取中的代码很简单,就是比较最左边的和最右边的还有中间值,谁是第二大就返回谁

三数取中代码如下

 

效率测试

有了三数取中效率明显有提升,但还是有人觉得不够快,确实,随着不断的递归递归层次越深效率会越来越慢,所以为了加快效率,我们可以进行小区间优化。

小区间优化代码如下

 
 

如上图分析可知最后一次递归消耗次数最多,所以我们可以对最后几个区间进行小区间优化,我们用快速排序来代替,根据上图有区间优化和无小区间优化有明显的提升。

那么可能会有人问这么一个问题为什么要选左边为key,并且选左边为key时要让右边先走,为什么相遇位置比key小。如下图


快排还有一个版本叫前后指针版本,我们先来看一下动图

我们可以看到分别定义了两个指针分别为prev和cur,这两个指针一前一后,cur前prev后,cur找小,找到小的就++prev,然后与cur位置的值进行交换,没找到就++继续找,直到cur的越界。

画图分析

代码如下

 

我们还有一个版本叫做挖坑法,这个版本没有效率的提升,但是可以 不用分析左边做key,右边先走的思想,也不用分析为什么相遇位置比key小的问题,因为它的相遇是坑。

我们看一下动图

此时left作为坑,右边找到小的之后与left交换然后left进行找大,而right的位置作为坑,直到相遇,因为相遇位置是坑我们直接把key的值填进去,我们可以定义一个临时变量作为坑

代码如下

 

前三个版本都使用了递归,若不用递归我们可以使用栈来实现,代码整体不变只需要要把递归部分改了,让key左右两个区间全部入栈,先入右边在入左边这样我们就可以先取到左边的,直到栈为空。

画图看一下

循环每走一次相当于一次递归 

 
 
 

1. 快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫快速排序

2. 时间复杂度:O(N*logN) 

3. 空间复杂度:O(logN)

4. 稳定性:不稳定


基本思想: 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 归并排序核心步骤

来看一下动图

画图分析

归并排序通过递归的方式将待排序的数组分解成更小的子数组,直到每个子数组只包含一个元素。然后,它将这些有序的子数组合并成越来越大的有序数组,直到最终得到一个完整的有序数组。这个过程中,分解是递归进行的,而合并则是通过迭代的方式完成的,每次合并两个有序的子数组来形成一个更大的有序数组。

代码如下

 

快排我们通过用栈来实现了非递归,那么我们归并的非递归怎么实现呢,我们可以按组来归并。

首先我们先分gap组,gap为每组的个数,比如gap为1那么每组就归一个数据,一个数据和一个数据归归并成2个有序数据,如果gap为2那么一组就是两个数据,2个数据和2个数据归最后归并成4个有序数据,直到gap等于数据个数就结束。

代码如下

 

这里有人可能要问为什么要i+=2* gap因为每组区间归并完后要进行下一段的区间归并,比如下标为0的和下标为1的进行11归那么他们归并完之后下一段区间开始归并也就是下标为2的要和下标为3的归并,每次要跳过2个组。

i为每组的起始位置,我们11归完后22归22归完后44归直到gap > n,但是这种方法有可能存在越界的风险

我们在对上面这组数据进行排序的时候就存在了越界的风险,除了begin1不会越界其他都越界了。处理方法如下

对于end1和begin2的越界处理方式非常简单就是不需要归并了,如果end2越界了我们只需要修正一下它的区间。代码如下

 

归并排序的特性总结

1. 归并的缺点在于需要O(N)的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问题。

2. 时间复杂度:O(N*logN)

3. 空间复杂度:O(N)

4. 稳定性:稳定


思想:计数排序又称为鸽巢原理,是对哈希直接定址法的变形应用。

操作步骤

1. 统计相同元素出现次数

2. 根据统计的结果将序列回收到原来的序列中

画图分析

代码如下: 

 

我们开了一个count数组用来记录原数组中元素出现的个数,那么这个数组开多大空间呢我们按范围开,找出最大值和最小值然后相减就是个数了,我们称他为相对映射

1. 计数排序在数据范围集中时,效率很高,但是适用范围及场景有限,只适合整数,适合范围集中。

2. 时间复杂度:O(n+range)

3. 空间复杂度:O(range)

4. 稳定性:稳定


这两个排序在面试中几乎不会考我们只需要了解即可。

基数排序的思想

基数排序是一种非比较型整数排序算法,其排序过程不需要进行元素间的比较。它的核心思想是将待排序的元素按照位数从低到高(或从高到低)进行排序,类似于对字符串的逐字符排序。具体来说,基数排序可以分解为多个稳定的计数排序过程,每个过程针对一个位数进行排序。

  1. 确定最大位数:首先,找到待排序元素中的最大值,从而确定最大位数。
  2. 逐位排序:从最低有效位(个位)开始,依次对所有元素进行一次稳定的计数排序,直到最高有效位(最高位)完成排序。在每一次排序中,都是根据当前位数的值,将元素分配到不同的桶(或称为子数组)中,然后按照桶的顺序合并元素,得到新的有序序列。
  3. 重复过程:重复上述过程,直到所有位数都排序完成。

基数排序的优点在于它的高效性和稳定性,尤其适用于整数的排序。然而,基数排序需要额外的存储空间来存储桶和计数数组,这可能会增加空间复杂度。


桶排序的思想

桶排序是一种将元素分到有限数量的桶中的排序算法。每个桶再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序,最后将各个桶中的数据有序地合并起来。

  1. 确定桶的数量:首先,需要确定桶的数量。桶的数量可以根据待排序元素的范围和分布来确定,通常选择比元素数量稍大一些的桶数量,以保证每个桶中的元素数量相对较少。
  2. 分配元素到桶中:根据一定的规则(如元素的范围、元素的某种属性等,将待排序的元素分配到相应的桶中。
  3. 桶内排序:对每个桶中的元素进行排序。这里可以使用任何适合的排序算法,如插入排序、快速排序等。由于桶内的元素数量相对较少,因此这一步的排序通常比较高效。
  4. 合并桶中的数据:最后,按照桶的顺序(通常是从第一个桶到最后一个桶)将桶中的数据合并起来,得到有序的结果。

桶排序的优点在于它对于一定范围内的数据排序非常高效,尤其是当数据分布相对均匀时。然而,桶排序的性能也依赖于桶的数量和桶内排序算法的选择。如果桶的数量选择不当或桶内排序算法效率不高,桶排序的性能可能会受到影响。

最新文章
AI-青鸟咨询公司logo设计+色彩基础知识
在品牌设计中如何正确的使用搭配,对色彩有基本了解,熟悉颜色间的关系,品牌案列关于色彩的解析。1.色彩基础知识 色彩能够吸引注意力,提升品牌形象,色彩就是人对于光反射产生的感觉,颜色可分为有彩色系和无彩色系,色彩三要素为:色相
Android 代码优化工具 —— Lint Checks
[技术鸟]公众号自开通以来,致力于给大家分享以“移动开发”为主的技术知识,希望与大家交流学习,相比于 iOS,Android 方面的分享少了很多,也得到部分粉丝的吐槽。 由于亦枫本人专职于Andro
AGI|这些火爆全网的AI热词你真的懂吗?
在数字化浪潮的推动下,人工智能(AI)已成为科技领域的热门话题,它以其独特的魅力和巨大的潜力,被众多行业视为下一个风口。然而,对于许多初入这一领域的人来说,AI所带来的不仅仅是前沿的技
494949最快开奖结果+香港,科学化方案实施探讨_XT13.943
随着数字彩票市场的蓬勃发展,人们对彩票开奖结果的关注度日益提高。本文将探讨494949最快开奖结果与香港科学化方案的实施,旨在为彩票行业提供更高效、透明的开奖流程。494949作为香港地区广受欢迎的数字彩票之一,其开奖结果的快速公布对
2025最新微信卡片生成教程
信息的传递方式正在经历着翻天覆地的变化。我们每天都在使用社交媒体,分享生活点滴,交流工作信息。而在众多社交平台中,微信以其庞大的用户基数和便捷的功能,成为了人们日常生活中不可或缺的一部分。随着微信功能的不断升级,一种新的信
AI加持的新搜索引擎可信嗎?
2個月前,聊天機器人ChatGPT橫空出世,其能像人類一樣撰寫文章並回答問題的能力震驚了世界。這種聊天機器人帶來的對於科技行業的顛覆力量如此之大,以至於它有可能徹底改變用戶使用互聯網的方式。包括微軟和谷歌在內的科技巨頭們已開始採取
6款最强国产AI视频生成工具,其中2款完全免费
离谱了,同学们!最近发现国产AI视频生成工具,生成质量非常不错哦,许多博主在各大短视频平台上,分发各种AI生成的短视频,随便一搞就是点赞破万,粉丝数蹭蹭往上涨,这势头绝了!咱完全可以直接借鉴学习,生成一些趣味感十足的AI视频,进
12月13日股市个人复盘小结
12月13日复盘:今日全市场成交金额:20898亿昨日全市场成交金额:18874亿市场情绪(1到5分):2分市场指数周期:第2周期市场主线情绪周期:客观第2周期,主观有转第3周期的迹象主线级别:2潜在机会板块前十(含周期):AIGC概念2、比亚迪概
HITACHI 新型台式的扫描电镜显微镜/望远镜
产品简介:  “TM4000"和“TM4000Plus"可简化从样品观察、图像确认到生成报告等一系列操作的过程,大幅提高工作效率。还标配了报告生成功能,观察结束后可十分轻松地将拍摄的图像制作成MicrosoftWord、Excel、PowerPoint格式的报告。此外
2024上海性博会|中国国际成人保健用品展
2024上海国际情趣生活及健康产业博览会展会简介上海国际情趣生活及健康产业博览会是一个注重实效性、专业性的高品质展会,是成人情趣用品领域极具规模和影响力的专业盛会。展览规模达16000平方米,是汇聚国内外250余家企业进行品牌推广、新
相关文章
推荐文章
发表评论
0评