算法-排序4(总结)

版权声明:本文为博主原创文章,随意转载,转载请注明出处! https://blog.csdn.net/penglei123456/article/details/85017097

如何实现一个通用的,高性能的排序算法。

总结一下前面学过的几种排序算法
算法 时间复杂度 是稳定排序 ? 是原地排序?
冒泡排序 O(n^2)
插入排序 O(n^2)
选择排序 O(n^2)
快速排序 O(n*logn)
归并排序 O(n*logn)
计数排序 O(n+k) k是数据范围
桶排序 O(n)
基数排序 O(dn) d是维度

线性排序时间复杂度比较低,但是对数据的要求十分严格,所以不能用作通用排序的方案。

小数据规模的排序,首选时间复杂度为 O(n^2) 的算法。如果数据规模较大,选择时间复杂度为 O(nlogn) 的算法。所以为了兼顾任意规模的数据排序,那就首选时间复杂度为 O(nlogn) 的算法。

归并排序和快速排序时间复杂度都为 O(n*logn),而且极端情况下快速排序的时间复杂度会变成 O(n^2),但是二者之间还是快速排序优先被选用。归并排序不是原地排序,在排序期间会申请同样数据大小的内存空间,所以空间复杂度上要高的多。

虽然优先选择的是快速排序,但是极端情况下时间复杂度会退化为 O(n^2),那么如何避免这种情况的发生呢?这就是接下来要总结的如何优化快速排序算法。

优化快速排序算法

当待排序数据呈现有序或者接近有序状态,每次分区选择的分区点都是最后一位的时候,快速排序算法时间复杂度退化为 O(n^2)。那么避免这种情况的发生就是每次选取的分区点,尽量将数据均分成两份。下面介绍两种选取分区点的方法。

方法一:三数取中法。分别获取分区区间的第一个,中间位置,最后一个元素,比较大小,选择中间的值作为分区点。如果分区区间的数据量过大,就可以采用五数取中,十数取中,尽量保证分区点的选择趋于中间数值。

方法二:随机法。随机在分区区间选择一个数据,根据概率来判断,分区点选到最小值或者最大值得概率是很小的,所以时间复杂度退化为 O(n^2) 的概率也是很小的。

算法实现举例分析

王争老师举例了 Glibc 中 qsort() 函数实现排序的原理。

qsort() 在数据量小的情况下会优选选择归并排序算法。当数据量比较大的时候,就会选择快速排序算法。使用快速排序的时候,对于分区点的选择,qsort() 函数采用的正是三数取中法。

在快速排序中,如果区间的元素个数小于等于 4,qsort() 就会采用插入排序对数据排序。因为在小数据规模下, O(n^2) 的值要小于 O(n*logn)。

总结

本文创作灵感来源于 极客时间 王争老师的《数据结构与算法之美》课程,通过课后反思以及借鉴各位学友的发言总结,现整理出自己的知识架构,以便日后温故知新,查漏补缺。

初入算法学习,必是步履蹒跚,一路磕磕绊绊跌跌撞撞。看不懂别慌,也别忙着总结,先读五遍文章先,无他,唯手熟尔~
与诸君共勉

关注本人公众号,第一时间获取最新文章发布,每日更新一篇技术文章。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/penglei123456/article/details/85017097
今日推荐