【算法】——八大排序理解篇

前言:

    排序有内部排序和外部排序,内部排序是在内存中进行的,外部排序是因为数据量过大,在内存中不能一次全部容纳。故在排序过程中访问硬盘等外存进行的。

    在这,我主要说内部排序:

    常用的内部排序算法有八种:


插入:

希尔排序VS直接插入排序

直接插入排序:

一句话总结:拿牌整牌(排排队)

    这有一堆牌,从顶部拿一张,在手中按顺序排列。


    每抽一张牌,和手里的牌(已排序的)进行比较,找到合适位置插入,再拿一张再比较.....直至所有的牌拿完。


    如上图,当插入元素与已排序中元素相等时,新元素插入在已排序元素的后面,即插入排序是稳定的

希尔排序:

    一句话总结:分组,插入排序,分组比

    Shell(希尔)排序也称为缩小增量排序。


    希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

    如n个数,则可取增量为d=n/2;

    所有距离为d的数放在同一个组中:如d=5,第1个和第6个数间距离为5,则第1和第6在一组。第2个和第7个之间距离为5,则第2个和第7个为一组.......

    先在各组内进行直接插入排序:如上图增量为5,5组分别进行直接插入排序。如上图第二行数;

    然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量  =1(  <  …<d2<d1),即所有记录放在同一组中进行直接插入排序为止:如上图最后一轮,增量为1。则整个分成1组,这1组进行直接插入排序。


对比:

    希尔排序是改进版的直接插入排序,

    希尔排序开始由于增量d取值大,每个子序列元素少,排序速度快,待排序后期,增量值逐渐变小,子序列元素变多,但由于前面的工作基础,大多数元素已经有序,所以排序速度快。比直接插入排序效率高。

    直接插入排序是稳定的,希尔排序是不稳定的。


选择:

简单选择排序VS堆排序

简单选择排序:

一句话总结:右上直角倒三角



    在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换;然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止。

    如上图:结果为:13、27、38、[49]、49、65、76、97

    但因为[49]本在49之后,但排完序后[49]在49的前面了,所以选择排序是不稳定的。


堆排序:

一句话总结:建堆取数重构堆

    堆:具有n个元素的序列(k1,k2,...,kn),当且仅当满足



    n个元素,初始化时,把要排序的n个数的序列看做一棵树,通过调整存储顺序,建立堆(小/大顶堆)。然后输出顶元素,将最后一个结点放在顶端空缺的位置,重构堆,重复上述操作,直至所有数取出。

    如6个数:84、79、46、38、40、56

树:


建堆:

    》》  

输出:84

重构堆:

   》》     》》

再输出79;

......

继而输出:84、79、56、46、40、38


对比:

    堆排序是一种树形选择排序,是对直接选择排序的有效改进。

    两者都是找到最小/大值,输出,再找再输出。但在查找过程中,选择排序是在所有剩余元素中查找。堆排序是在顶元素的左/右子树或更深一层左/右子树的左/右子树中找,所以效率会高一些。

    选择排序和堆排序都是不稳定的。


交换:

冒泡排序VS快速排序

冒泡排序:

一句话总结:左上直角倒三角


    在一列要排序的元素中,从顶端第一个开始,依次向下进行比较,若发现小数在下,则进行交换,大数继续向下比较,即:大数下沉,小数上浮。

如第一列:49与38比较,49大,下沉,38上浮。

然后38与65比较,不变

......

最后,最大的97在最低端。


快速排序:

一句话总结:基准两边排

    1)选择一个基准元素,通常选择第一个元素或者最后一个元素,
    2)通过一趟排序将待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的 元素值比基准值大。
    3)此时基准元素在其排好序后的正确位置
    4)然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序。
如:


全过程:


对比:

    快速排序是冒泡排序的改进。快速排序,首先定一个基准,小的上浮,大的下沉。分组后,在各组中再次进行相同的操作。

    冒泡排序是稳定的,快速排序是不稳定的。


归并排序:

一句话总结:二路归并

    归并排序就是使用合并操作完成排序的算法。


    归并排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。


基数排序:

一句话总结:个十百千万

    基数排序,是先按个位排序,排好序后,再按十位排,依次按更高位排。

如:


总结:



选择排序算法准则:

    每种排序算法都各有优缺点。因此,在实用时需根据不同情况适当选用,甚至可以将多种方法结合起来使用。

选择排序算法的依据

    影响排序的因素有很多,平均时间复杂度低的算法并不一定就是最优的。相反,有时平均时间复杂度高的算法可能更适合某些特殊情况。同时,选择算法时还得考虑它的可读性,以利于软件的维护。一般而言,需要考虑的因素有以下四点:

1.待排序的记录数目n的大小;
2.记录本身数据量的大小,也就是记录中除关键字外的其他信息量的大小;
3.关键字的结构及其分布情况;
4.对排序稳定性的要求。

就时间复杂度而言:

    当原表有序或基本有序时,直接插入排序和冒泡排序将大大减少比较次数和移动记录的次数,时间复杂度可降至O(n);

    而快速排序则相反,当原表基本有序时,将蜕化为冒泡排序,时间复杂度提高为O(n2);
    原表是否有序,对简单选择排序、堆排序、归并排序和基数排序的时间复杂度影响不大。

就元素多少而言:

设待排序元素的个数为n.
1)当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序、堆排序或归并排序序。
    快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;
    堆排序 :如果内存空间允许且要求稳定性的;
    归并排序:它有一定数量的数据移动,所以我们可能过与插入排序组合,先获得一定长度的序列,然后再合并,在效率上将有所提高;
2)当n较大,内存空间允许,且要求稳定性,则选择归并排序;
3)当n较小,可采用直接插入或直接选择排序。
    直接插入排序:当元素分布有序,直接插入排序将大大减少比较次数和移动记录的次数。
    直接选择排序 :元素分布有序,如果不要求稳定性,选择直接选择排序;
5)一般不使用或不直接使用传统的冒泡排序。
6)基数排序
    它是一种稳定的排序算法,但有一定的局限性:
1、关键字可分解。
2、记录的关键字位数较少,如果密集更好
3、如果是数字时,最好是无符号的,否则将增加相应的映射复杂度,可先将其正负分开排序。





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值