软件设计师考试 - 排序算法

软件设计师考试 - 排序算法

   一、排序的概念

   1. 稳定排序与不稳定排序

   稳定排序:相等元素排序后相对位置不变。

   不稳定排序:相等元素相对顺序可能颠倒。

   2. 内排序(内存排序)和外排序(外部存储排序)

   二、排序方法分类

   1.  插入类排序: 直接插入排序、希尔排序

   2. 交换类排序: 冒泡排序、快速排序

   3. 选择类排序: 简单选择排序、堆排序

   4. 归并排序

   5. 基数排序 

   三、常见的排序算法介绍

   1.  直接插入排序

   直接插入排序:即当插入第个记录时,R1,R2,...,Ri-1 均已排好序,因此,将第 i 个记录 Ri 依次与Ri-1,…,R2,R1进行比较,找到合适的位置插入。它简单明了,但速度很慢。

   排序思路:

   1. 首先将前面两个元素进行比较,按照从小到大的顺序

   2. 上面比较之后,得到一个有两个元素的有序数列。再将第三个元素与前面最大的元素相比,直到找到比它自己小的元素,插入到其后面...

   如下图:

20260618-121205

   时间复杂度:O(n²);空间复杂度:O(1)

   2. 希尔排序

   希尔排序:先分组,经过前面几轮比较后,基本有序,再进行直接插入排序,彻底分配好

   排序思路:当排序的数列比较小的时候,直接插入排序的效率还可以 (缩小解决问题的规模

   如下图:

image

   说明:希尔排序比直接插入排序要复杂一些,结合直接插入排序。这个相隔距离(d1)初始值=N(元素个数)/2,原则上没有规定是取奇数还是偶数,只要是接近的整数就行,以此类推,最后相隔距离会变为1,即只有一组,此时按照直接插入排序的方法进行排序后,排序就结束了。

   时间复杂度:O(n²);空间复杂度:O(1)

   3. 直接选择排序

  直接选择排序的过程是,首先在所有记录中选出排序码最小的记录,把它与第1个记录交换,然后在其余的记录内选出排序码最小的记录,与第2个记录交换。依次类推, 直到所有记录排完为止。

  排序思路:非常简单,每次找到剩余元素中最小的元素,然后进行记录交换。

  如下图:

image

  时间复杂度:O(n²);空间复杂度:O(1)

  4. 堆排序

  设有 n 个元素的序列 {K1,K2, ... ,Kn}, 当且仅当满足下述关系之一时,称之为堆。
  (1) ki ≤ k2i 且 ki ≤ k2i+1 

  (2) ki ≥ k2i 且 ki ≥ k2i+1 

  其中 (1) 称为小顶堆,(2) 称为大顶堆

  堆排序分为两个大的步骤:初建堆 和 堆排序

  1)初建堆 (涉及很多调整)

  •   建立堆的过程按照完全二叉树来顺次放置结点
  •   对所有内部节点进行挑中:从最后一个非叶子节点开始进行调整,将其与自己的孩子节点比较(注意:非叶子节点如果有多级结点,要调整到最后一级结点),然后从倒数第二个非叶子节点进行调整,依次类推,直到最后从根节点调整后结束。

  如下图:

image

  2)堆排序

  •   取走堆顶元素
  •   重建堆: 将完全二叉树的最后一个结点放置到堆顶,然后从堆顶元素进行调整(堆的重建)

  如下图:

image

  总结:

  堆排序思路: 初建堆(涉及很多调整),拿走堆顶,重建堆,再拿走堆顶,依此类推。

  堆排序: 效率高,适用于元素特别多,不需要将所有元素进行排序,只需要选出前N个(一部分极值)。

  时间复杂度:O(n㏒n);空间复杂度:O(1)

  5. 冒泡排序

  冒泡排序的基本思想是,通过相邻元素之间的比较和交换,将排序码较小的元素逐渐从底部移向顶部。由于整个排序的过程就像水底不的气泡一样逐渐向上冒,因此称为冒泡算法。  

  如下图:

image

   注意:下标的变化范围

   时间复杂度:O(n²);空间复杂度:O(1)

   6. 快速排序

   基本思路:先找一个“标准”,把数组分成两边,然后左右继续重复这个过程。(分治法,采用递归,选取基准元素。)

   如下图:

image

   时间复杂度:O(n㏒n);空间复杂度:O(㏒n)

   7. 归并排序

   归并排序:不断比较两个有序序列当前最前面的元素,把较小的放入结果数组,并移动对应指针,直到合并完成。

   基本思路:分组、合并(将问题进行拆解)

   如下图:

image

   关于合并过程,这里展开一下: 

   假设有两个已经排好序的数组:

   A = [2, 5, 8, 12]
   B = [1, 3, 7, 10]
   i → 指向 A 当前要看的位置
   j → 指向 B 当前要看的位置 

  一开始:

  i = 0 → A[0] = 2
  j = 0 → B[0] = 1

  比较:A[i] 这个数 和 B[j] 这个数 谁更小。谁小,谁放进结果数组 R。 

  第一步:2 vs 1 → 1 更小

  所以:R = [1] 并且 j++

  第二步:A [0] = 2  B [1] = 3

  比较:2 vs 3 → 2 更小 

  所以:R = [1 , 2]  并且 i++

  ... 

  每次比较 A[i] 和 B[j]
  谁小谁放入结果数组 R 并且 对应指针后移。直到其中一个数组用完,当一个数组遍历完后,将另一个数组剩余元素直接加入结果数组。

  时间复杂度:O(n㏒n);空间复杂度:O(n)

  四、排序算法比较

image

    从上图可以看出:

    稳定的排序算法有:直接插入排序、冒泡排序、归并排序、基数排序

    效率较高的排序算法有:堆排序、快速排序、归并排序

posted @ 2026-06-18 11:18  欢乐豆123  阅读(3)  评论(0)    收藏  举报