排序算法总结

1参考图解排序算法之冒泡排序 (qq.com)

对于数组呢,排列的是五花八门的,但是总有可能出现还没排序的时候人家就是有序数组,还有可能呢是第一层 for 循环遍历了一半数组就变得有序了,那这些情况有序了我们就不用再比较了,浪费时间。

如何知道有序呢:第二层 for 循环的时候,没有交换的元素。增加一个 flag 数组,如果第二层循环没有交换元素的时候,证明数组已经排序好了,不需要再继续遍历,直接返回。

2参考图解排序算法之选择排序 (qq.com)

选择排序,从数列中选出最小(大)的元素,放在序列起始位置,接着在未排序序列中找出最小(大)元素,放已排序序列的末尾。选择排序不稳定(稳定是不会改变相同元素的相对位置)。

3参考图解排序算法之插入排序 (qq.com)

        选择待排序序列的第 1 个元素作为有序序列,将剩余元素当作未排序序列;

        从未排序序列中选择第 1 个元素,与有序序列中的元素依次比较,将其插入到合适的位置(通过这个可以看出插入排序稳定的特性);

        重复上一步,直至未排序序列无元素可进行插入时,停止操作,此时序列全部有序。

4参考图解排序算法之希尔排序 (qq.com)

希尔排序,又叫缩小增量排序,是一种改进的更高效的插入排序

        首先确定数组元素的间隔(gap)值,一般 gap = length/2;

        将数组元素按照 gap 从第 1 个元素开始分成若干个子数组(即位置相隔为 gap 的元素为一个子数组),分别对各子数组进行直接插入排序(可以看出希尔排序不稳定);

        减小 gap 值,一般 gap = gap/2,并重新将整个数组按照新的 gap 值分成若干个子数组,并分别对各子数组进行直接插入排序,直至 gap = 1,排序结束。

当gap=1就是直接插于排序

以上四种都是时间复杂度O(n^2),空间复杂度O(1)

5参考图解排序算法之快速排序 (qq.com)

快速排序(QuickSort),又叫分区交换排序,简称快排,它是对冒泡排序的一种改进,运用了分治算法

        挑数。从数组中挑选出一个元素,这个元素叫“基准(pivot)”(为了方便,一般选择第 1 个元素)

        划分。将数组划分成两部分,将待排序数组中小于 pivot 的数移动到左边,将大于 pivot 的数移动到右边,这时两部分子数组的元素相对有序。(这个操作也叫“分区(partition)”操作,如果是等于 pivot 的数可以放在任何一边,可以看出快速排序不稳定这个特性无法保证相等的数据按初始的位置存放

        求解。将两个分区的元素按照第 2 步的方式继续对每个分区找出 pivot,然后移动,直至每个分区只有 1 个元素为止。

主要使用双指针法,选择第 1 个元素作为 pivot,双指针 i 和 j 分别指向数组最左边和最右边,j 从右向左找比 pivot 小的数,i 从左向右找比 pivot 大的数,然后交换,因为 pivot 一般选取的是最左边的值,所以是 j 先移动

时间复杂度O(nlogn)~O(n^2),空间复杂度O(logn)~O(n)

6参考图解算法之归并排序 (qq.com)

归并排序(MergeSort),对于待排序数组,将其从中间位置分为前后两个部分,对两部分分别排序,将两个已经排序的子数组合并成一个数组,这样达到数组整体有序。

        划分(Divide)将待排序数组分为两个均等的子数组;

        求解(Conquer)分别对两个子数组进行排序(即对两个子数组递归执行归并排序)(终止就是将每个子数组拆分成只剩下一个元素的时候);

        合并(Combine)将两个已经排序的子数组合并成一个完整的有序数组,得到最终结果(在合并过程中,如果是元素数值相同,则不会改变位置,所以归并排序是稳定的排序算法)

时间复杂度是O(nlogn),空间复杂度O(n)

7参考图解排序算法之堆排序 (qq.com)

堆排序是选择排序的优化。堆默认是一棵完全二叉树,而且每一个节点的值都必须大于等于(或者小于等于)其子树中每个节点的值。将数组构造成一个大顶堆或者小顶堆,每次取走堆顶元素,再将剩下的堆调整为大顶堆或者小顶堆。

        构建堆。将待排序数组构造成一个大顶堆(或者小顶堆);(使用的是数组,而不是二叉树,我们可以把数组的样式想成是一棵二叉树)

        堆排序。将堆顶元素取出(大顶堆为最大值,小顶堆为最小值),将其与末尾元素进行交换,此时末尾元素就成了最大值(或者最小值);(在交换数据的时候是栈顶元素和末尾元素交换,可能存在改变相同的值相对位置的情况,所以堆排序不是稳定的排序算法)

        调整堆。将剩余元素重新构成一个堆,重复第 2 步,交换堆顶元素与当前末尾元素,最终使得整个数组有序,得到一个有序数组

时间复杂度是O(nlogn),空间复杂度是O(1)

8参考图解排序算法之桶排序 (qq.com)

“桶”是指一种数据结构,代表一个区间范围,用于临时存储排序元素。桶排序(BucketSort),一种分布式排序算法,将待排序数组元素分到有限数量的桶里,每个桶里的数据分别进行排序, 按照桶的顺序将元素合并成有序数组

        初始化 m 个桶,将 n 个元素分配到 m 个桶中;(分配的规则有很多,为了好理解,我在本文使用待排序元素整除的方式,这样可以将元素较为均匀的分配到各个桶中,比如每个元素值 / 10 来分配桶)

        对每个桶内的数据分别进行排序,这里可以借助任意排序算法;(桶排序是否稳定取决于这里借助的排序算法,比如你选择的如果是插入排序,那桶排序就是稳定的,比如你选择的是堆排序,那这个时候的桶排序就不是稳定的)

        按照桶的从大到小的顺序,将所有元素合并成有序数组

时间复杂度分为两部分:1将 n 个待排序元素分配到 m 个桶中,平均每个桶中有 n / m 个元素,这需要从左到右遍历数组,时间复杂度为 O(n);2每个桶内再次排序的时间总和

桶排序中,需要创建 m 个桶的额外空间,空间复杂度为 O(m),此外创建了长度为 n 的 res 数组存储排序后的数组,空间复杂度为 O(n),所以总的空间复杂度为 O(n + m)

桶排序的效率依赖于桶的选择和数据的分布情况,主要适用于两个场景:1. 待排序数组的元素分布均匀,这样可以使桶排序发挥出更好的性能;2. 应用于外部排序,当待排序数组的数据量特别大,无法一次性的加载到内存中,可以将数据分到多个桶里,在内存中逐个读取并排序每个桶,最后将每个桶的数据写回到外部存储中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值