笔试之排序算法(一)

排序(升序)

0. 冒泡排序

0.1 算法思想

  • 临近的数字两两进行比较,逆序则交换,一趟过去最大的元素被放到最后一位。
  • 再对前n-1个元素进行上述操作,直到第一个元素

0.2 性能分析

  • 最坏情况:
    • 比较次数:(N-1)+(N-2)+……+2+1=N(N-1)/2~ N2/2
    • 交换次数:同上
  • 最好情况:
    • 比较次数:(N-1)+(N-2)+……+2+1=N(N-1)/2~ N2/2
    • 交换次数:0

0.3 特点

存在不足:就是本来位于前面的较小数被交换到后面

1. 选择排序

1.1 基本思想

  • 找到数组中最小的元素
  • 将它与数组的第一个元素交换位置
  • 再次,剩下的元素找最小的元素与数组的第二个元素交换位置
  • 直到最后一个元素
    即不断选择剩余元素的最小者,与第n个元素交换,直至整个数组有序

1.2 性能分析

  • 交换次数总是N
  • 比较次数约为 N2/2
    • 0-N-1的任意i都会进行 N1i 次比较,故 (N-1)+(n-2)+……2+1=N(N-1)/2~ N2/2 次比较

1.3 特点

  • 当前索引左边都是有序的
  • 一次确定一个元素的位置
  • 数据移动最少,N次交换,每次只会改变两个元素的值
  • 比较平均,与初始序列无关,没有最好最坏

2. 插入排序

2.1 基本思想

将一个数据插入到已经排好序的有序数据中。
从后往前找,当插入元素<第n个元素时,交换二者,直到插入元素>=第n个元素

2.2 性能分析

  • 最坏情况:逆序
    • 比较次数:1+2+……+N-1=N(N-2)~ N2/2
    • 交换次数:1+2+……+N-1=N(N-2)~ N2/2
  • 最好情况:有序
    • 比较次数:N-1,每次插入只需要一次比较
    • 交换次数:0

2.3 特点

  • 需要给插入元素腾出空间,将插入位置之后的元素右移。实际中为,每次比较,都一次交换
  • 需要初始顺序有关,部分有序的数组比随机数组快的多

3. 希尔排序

3.1 基本思想

  • 基于插入排序,交换不相邻元素,对数组局部进行排序,并最终用插入排序将局部有序的数组排序。
  • 使数组中间隔为h的元素都是有序的。h-子数组中交换到比它大的元素之前去,只需要将插入排序代码移动元素的距离由1改为h即可。

3.2 性能分析

  • 透彻理解希尔排序的性能至今仍然是一项挑战。达不到平方级别,最坏情况下,比较次数与N^(3/2)成正比
  • 不需要额外的空间

3.3 特点

  • 间隔序列的选择会影响排序效率
  • 排序之初,各子数组很短,排序之后各子数组部分有序。两种情况都适合插入排序

4. 归并排序

4.1 算法思想

  • 将两个有序数组,归并成一个更大的有序数组。
  • 原地归并:需要一个辅助数组,i,j分别作为两个数组的哨兵。a[i]?a[j],第一个数组的第i个元素小,则将该元素放入辅助数组,i++;同理。直到其中一个数组的元素用尽,即i>mid或j>hi,则直接取另外一个数组的元素,直至全部用尽。

4.2 性能分析

  • 递归实现和非递归实现,都需要1/2NlgN至NlgN次比较
  • 一个长度为N的辅助数组
  • 最坏情况需要NlgN次比较

4.3 特点

  • 最坏情况下,归并排序最好
  • 空间复杂度不是最优

5. 快速排序

5.1 算法思想

  • 分治思想:将一个数组分成两个子数组,将两部分独立地排序。
  • 切分:切分元素的位置排定,之前的所有元素不大于它,之后所有元素不小于它。两个指针头指针i,尾指针j,从左往右扫描数组,直到找到大于等于切分元素的a[i],从右往左扫描数组,直到找到小于等于切分元素的a[j],交换a[i]和a[j]的位置,直到指针i和j相遇。

5.2 性能分析

最好情况是切分元素每次都能把数组对半分,此时比较次数为NlgN
最坏情况是切分不平衡,第一次从最小元素切分,第二次从第二小的元素切分,此时比较次数约 N2/2
空间复杂度lgn(递归辅助栈)

5.3 特点

  • 实现简单,运用广泛
  • 原地排序(只需要一个很小的递归辅助栈)
  • 与初始序列(切分元素的顺序)有关
  • 缺点是非常脆弱,很容易达到最坏情况,平方级别的时间复杂度

6. 堆排序

6.1 算法思想

  • 数组实现的二叉堆,二叉树的每个节点都大于等于两个子结点,按层级顺序放入数组,位置k个父节点为k/2,两个子结点分别为2k,2k+1
  • 所有元素插入最小堆,再重复调用删除最小元素的操作,按顺序删去。
  • 将排序的数组作为堆本身,无需额外空间

6.2 性能分析

唯一能够同时最有利用空间和时间的方法,最坏情况下~2NlgN次比较

6.3 特点

  • 无法利用缓存,很少和相邻的其他元素进行比较,缓存未命中次数远远高于其他算法

总结:

  • 任何一个基于比较的排序算法,比较次数都大于等于NlgN
  • 稳定的:冒泡排序、插入排序和归并排序,其他都不稳定。
  • 逆序时达到最坏情况:插入排序,快速排序
  • 顺序时达到最坏情况:快速排序
  • 找n个数的中位数,可以在O(n)时间内完成
  • 最好情况最快的是插入排序比较次数为N-1
    笔试之排序算法(一)_第1张图片

你可能感兴趣的:(数据结构)