几个排序算法的理解性总结(自用,入门向)

  1. 插入:将一个元素看作有序序列,把第二个元素到最后一个元素当作未排序序列,从头到尾扫描未排序序列,将扫描的每个元素插入到有序序列的适当位置(寻找适当位置要花n的时间,又得寻找n个元素的适当位置)。它稳定,时间复杂度n2,空间复杂度1

  2. 希尔:对于插入算法,如果一个序列基本有序,基本有序到查找下个元素插入到有序序列的适当位置十分简单,可能只需要比较1个元素就能找到,不需要花费n的时间。希尔说可以先把数据分成d组,d的初始值一般取元素/2的整数个,比如9个元素分成4组,每组2个元素。第一次每组只有2个元素,在组内进行排序,组内排序完成以后,第二次把元素重新划分成2组,这样这重新划分的2组,每组内的元素就基本有序了,它们组内排序只需要1的时间。如此循环至只能分成1组,就排完了。它不稳定,时间复杂度n1.3,空间复杂度1

  3. 选择:从已有的选择最大的放到后面。它不稳定,时间复杂度n2,空间复杂度1

  4. 堆排序:选择排序中,选出一个最大的放到后面,中间要经过很多次比较,如果这些比较结果能够保留,那么下次再选最大的时候就能少比较。Floyd说了,整个大根堆(每个节点比它的左孩子和右孩子大),第一次选择最大的时候(一棵普通完全二叉树变成大根堆),比较结果保存的好好的,下次还能用。但你换结构了诶,这个结构怎么比较,怎么构建嘞?Floyd说你先按照原来那个数组的顺序,构造个完全二叉树(用顺序结构存储),然后从最后一个元素开始,看看它比父节点和兄弟节点大不,大了咱就得当爹了(但得注意,当爹了以后还要注意那个原来的父亲是不是比他原来的孙子还小,那他还得下移,这点和选择排序不同,选择排序选出来最大的就行了,但堆排序选出来最大的还得分个等级),就这样到了根节点,比较完了,第一个堆也就构建好了,花了咱n*logn的时间(选择排序每趟选最大的时间才n,但不怕,比较的结果咱在大根堆保留下来了,下次比较就没必要比较很多次了)。大根堆建好了,把根节点弄出来,它是最大的。然后用数组最后一个元素把根节点替换掉,再对这个少了个节点的完全二叉树重新建堆。这时候Floyd露出邪魅的笑容,你看,这大根堆重建的时候多简单,现在的根节点直接下移到合适的位置,其他地方都比较好了,根本不用管,时间复杂度也就logn。注意:升序用大根堆,降序用小根堆。它不稳定,时间复杂度nlogn,空间复杂度1

  5. 冒泡(交换):每一个元素都和它下一个元素比较,大的往后移一位。那么最大的一定会沉底。该算法问题在于,如果是最大的后移为标准,那么最小的第一趟排序不一定上浮到顶端。而完成排序必然会是最小的上浮到顶端,这样会导致无效的比较次数增多。它稳定,时间复杂度n2,空间复杂度1

  6. 快速:是这样啊,假如我拿出一个数组里的第一个值x,经过某种变换策略,使得x前面的都比它小,后面的都比它大,那我这个x的位置就是最后排序完成的位置了啊,那之后的操作就不会再有与x进行比较了吧。虽然和Hoare说的不太一样,但其实也就是拿出来那个x,然后遍历后边的数,比x大的放前面,小的放后面。然后再把x前面的所有数单独拿出来,再走一遍流程,后边的所有数也是一样。这样的话,每次比较都是有意义的,没有一次比较是重复的、没有必要的。直到完成排序。它不稳定,时间复杂度nlogn,空间复杂度logn(要个栈实现递归)

  7. 归并:这个啊,是这样,不知道是谁有天闲的没事提出来个问题,说是如果要把两个有序的序列合并为一个有序序列,要花费多长时间,咋做呢。某大佬说,你这样,你把这两个序列的第一个元素进行比较,小的你拿出来放在一个新数组里边,然后把那个元素从原来那个序列里面删掉,然后在那俩序列里面继续拿第一个元素比较,小的元素拿出来,原序列删掉该元素。然后呢,等到一个序列被掏空了,那直接把另一个序列往你新建的那个数组后边一放,就完事了,这样即利用了原来的两个序列有序,也没多做比较。做的比较都是以前没做的比较,花费时间也不多,总比你合并之后再用个啥排序算法好得多。后来这大佬一想不对劲,只有一个元素的数组,它也是有序序列啊?给出一个无序序列,这里面每个元素都作为一个有序序列,然后逐渐两两合并成一个有序序列(假如是一个8元素数组,也即有8个有序序列,把这8个有序序列两两合并,得到4个2元素有序序列,再合并得到2个4元素有序序列,再合并得到1个8元素有序序列,ok,排好序了,没做任何一个重复的比较),那以前那抵消的排序算法里重复比较的问题不就解决了?它是稳定的,时间复杂度nlogn,空间复杂度n(要有个新数组吧)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值