软考-软件设计师:排序算法-归并排序

介绍

归并也称为 合并,归并排序是一种基于 分治法(Divide and Conquer) 的排序算法,思想是:

  • 分(Divide):把待排序的数组 不断拆分成两个子数组,直到每个子数组 只有 1 个元素(单个元素天然有序)。

  • 治(Conquer):把拆分后的 子数组两两合并,合并时按照从小到大(或从大到小)的顺序排列,最终得到一个有序数组。

例子

假设我们有一个初始数列为

{8, 4, 5, 7, 1, 3, 6, 2}

整个归并排序的过程如下图所示

每次合并时,比较大小,比如:将小的放在前面

可以看到这种结构很像一棵 完全二叉树,本文的归并排序我们采用递归去实现(也可采用迭代的方式去实现)。

分阶段可以理解为就是递归拆分子序列的过程,递归深度为 O(nlog₂n)

参考:
https://blog.csdn.net/justidle/article/details/104203958

上图最后一步:合并两个有序数组流程

如上图中的最后一次合并,要将 [4,5,7,8] 和 [1,2,3,6] 两个已经有序的子序列,合并为最终序列 [1,2,3,4,5,6,7,8],步骤如下:

比较次数

比较 n/2 次,n 是总元素的个数

参考:
https://blog.csdn.net/justidle/article/details/104203958

时间复杂度

O(nlog₂n)

执行 log₂n 趟,每趟比较 n 次(不到 n 次)

时间复杂度-最好

O(nlog₂n)

时间复杂度-最坏

O(nlog₂n)

空间复杂度

O(n)

有上图可知,需要额外的数组存储合并结果

是否稳定

稳定
合并时遇到 两个元素相等, 会优先取左数组的元素

题

两个递增序列 A 和 B 的长度分别为 m 和 n(m<n 且m与n接近),将二者归并为一个长度为 m+n 的递增序列。当关系为()时,归并过程中元素的比较次数最少。

分析

选项A
  1. a1 与 b1比较,a1 小,temp=[a1]
  2. a2 与 b1比较,a2 小,temp=[a1,a2]
  3. a3 与 b1比较,a3 小,temp=[a1,a2,a3]
  4. …..
  5. am 与 b1比较,am 小,temp=[a1,a2,a3,…am]

比较 m 次,此时 b1 比 A 所有元素大,就不需要比较了,将 B 序列中元素复制到 temp 中,即:temp=[a1,a2,a3,…am,b1,b2,…bn]

选项B
  1. b1 与 a1比较,b1 小,temp=[b1]
  2. b2 与 a1比较,b2 小,temp=[b1,b2]
  3. b3 与 a1比较,b3 小,temp=[b1,b2,b3]
  4. …..
  5. bn 与 a1比较,bm 小,temp=[b1,b2,b3,…bn]

比较 n 次,此时 a1 比 B 所有元素大,就不需要比较了,将 A 序列中元素复制到 temp 中,即:temp=[b1,b2,…bn,a1,a2,a3,…am]

题干给出 m<n,所以错

选项C

当 bm 比 am大时,就不需要比较了,前面有 m 个 a,m-1 个 b,即:比较 m + m - 1 = 2m - 1 次

选项D

当 bm+1 比 am大时,就不需要比较了,前面有 m 个 b,和 m 个 a ,即:比较 2m 次

答案

题中给出 m<n,所以选择 A

参考:
https://blog.csdn.net/justidle/article/details/104203958


原文出处:/show_1GWwqGH7DD9.html