排序算法详解

目录

冒泡排序(交换)

快速排序(交换)

选择排序(选择)

堆排序(选择)

简单插入排序(插入)

希尔排序(插入)

归并排序

计数排序


冒泡排序(交换)

相邻的两个数比较,较大的往后移,每次下去数列最后一个是里面最大的。

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

快速排序(交换)

基本思想:

对于如何按照基准值将待排序列分为两子序列,常见的方式有:

1、Hoare版本

2、挖坑法

3、前后指针法

时间复杂度:O(NlogN)

两个优化的方法:

三数取中:

小区间优化

为了减少递归树的最后几层递归,我们可以设置一个判断语句,当序列的长度小于某个数的时候就不再进行快速排序,转而使用其他种类的排序。小区间优化若是使用得当的话,会在一定程度上加快快速排序的效率,而且待排序列的长度越长,该效果越明显。

选择排序(选择)

选择排序,即每次从待排序列中选出一个最小值,然后放在序列的起始位置,直到全部待排数据排完即可。

时间复杂度:O ( N 2 ) 空间复杂度O ( 1 )

优化:

可以一趟选出两个值,一个最大值一个最小值,然后将其放在序列开头和末尾,这样可以使选择排序的效率快一倍。

堆排序(选择)

 

要学习堆排序,首先要学习堆的向下调整算法,因为要用堆排序,你首先得建堆,而建堆需要执行多次堆的向下调整算法。堆的向下调整算法(使用前提):

 若想将其调整为小堆,那么根结点的左右子树必须都为小堆。

 若想将其调整为大堆,那么根结点的左右子树必须都为大堆。

基本思想

1.从根结点处开始,选出左右孩子中值较大的孩子。

2.让大的孩子与其父亲进行比较。

若大的孩子比父亲还大,则该孩子与其父亲的位置进行交换。并将原来大的孩子的位置当成父亲继续向下进行调整,直到调整到叶子结点为止。

若大的孩子比父亲小,则不需处理了,调整完成,整个树已经是大堆了。

时间复杂度:O(NlogN) O(1)

简单插入排序(插入)

插入排序,又叫直接插入排序。实际中,我们玩扑克牌的时候,就用了插入排序的思想。

基本思想:

在待排序的元素中,假设前n-1个元素已有序,现将第n个元素插入到前面已经排好的序列中,使得前n个元素有序。按照此法对所有元素进行插入,直到整个序列有序。

时间复杂度:O ( N 2 )

空间复杂度:O ( 1 )

希尔排序(插入)

 

将待排序列进行一次预排序,使待排序列接近有序,然后再对该序列进行一次直接插入排序。因为此时直接插入排序的时间复杂度为O(N),那么只要控制预排序阶段的时间复杂度不超过O(N2)。

基本思想

1.先选定一个小于N的整数gap作为第一增量,然后将所有距离为gap的元素分在同一组,并对每一组的元素进行直接插入排序。然后再取一个比第一增量小的整数作为第二增量,重复上述操作…

2.当增量的大小减到1时,就相当于整个序列被分到一组,进行一次直接插入排序,排序完成。

时间复杂度:O ( N l o g N )   空间复杂度:O ( 1 )

归并排序

 

归并排序是采用分治法的一个非常典型的应用。

基本思想:

将已有序的子序合并,从而得到完全有序的序列,即先使每个子序有序,再使子序列段间有序。

递归与非递归实现

递归:归并排序,从其思想上看就很适合使用递归来实现,并且用递归实现也比较简单。其间我们需要申请一个与待排序列大小相同的数组用于合并过程两个有序的子序列,合并完毕后再将数据拷贝回原数组。

非递归:归并排序的非递归算法并不需要借助栈来完成,我们只需要控制每次参与合并的元素个数即可,最终便能使序列变为有序

计数排序

计数排序,又叫非比较排序。顾名思义,该算法不是通过比较数据的大小来进行排序的,而是通过统计数组中相同元素出现的次数,然后通过统计的结果将序列回收到原来的序列中。

计数排序只适用于数据范围较集中的序列的排序,若待排序列的数据较分散,则会造成空间浪费,并且计数排序只适用于整型排序,不适用与浮点型排序。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

故曦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值