目录

数据结构排序

数据结构(排序)

文章目录


一、排序概念

1.1 概念

  • 排序:所谓排序,就是使⼀串记录,按照其中的某个或某些关键字的⼤⼩,递增或递减的排列起来的操作。

1.2 常见的排序算法

https://i-blog.csdnimg.cn/direct/a79d721a45f34be5a56118443c853386.png

二、实现常见的排序算法

2.1 直接插入排序

void InsertSort(int* arr, int n) { for (int i = 0; i < n - 1; i++) { int end = i; int tmp = arr[end + 1]; while (end >= 0) { if (arr[end] > tmp) { arr[end + 1] = arr[end]; end–; } else { break; } arr[end + 1] = tmp; } } }

  • 当插⼊第 i(i>=1) 个元素时,前⾯的 array[0],array[1],…,array[i-1] 已经排好序,此时⽤ array[i] 的排序码与 array[i-1],array[i-2],… 的排序码顺序进⾏⽐较,找到插⼊位置即将 array[i] 插⼊,原来位置上的元素顺序后移:

https://i-blog.csdnimg.cn/direct/24385dc5122d4ed1936e8d184285a825.png 直接插⼊排序的特性总结

  1. 元素集合越接近有序,直接插⼊排序算法的时间效率越⾼
  2. 时间复杂度:O(N^2)
  3. 空间复杂度:O(1)

2.2 希尔排序

void ShellSort(int* arr, int n) { int gap = n; while (gap > 1) { int gap = gap / 3 + 1; //保证最后一次的 gap 是 1。 for (int i = 0; i < n - gap; i++) { int end = i; int tmp = arr[end+gap]; while (end >= 0) { if (arr[end] > tmp) { arr[end + gap] = arr[end]; end-=gap; } else { break; } } arr[end + gap] = tmp; } } }

  • 希尔排序法⼜称缩⼩增量法。希尔排序法的基本思想是:先选定⼀个整数(通常是gap = n/3+1),把待排序⽂件所有记录分成各组,所有的距离相等的记录分在同⼀组内,并对每⼀组内的记录进⾏排序,然后gap=gap/3+1得到下⼀个整数,再将数组分成各组,进⾏插⼊排序,当gap=1时,就相当于直接插⼊排序。
  • 它是在直接插⼊排序算法的基础上进⾏改进⽽来的,综合来说它的效率肯定是要⾼于直接插⼊排序算法的: https://i-blog.csdnimg.cn/direct/ecde5373b52440db8480c64f5fc5da76.png 希尔排序的特性总结
  1. 希尔排序是对直接插⼊排序的优化。
  2. 当 gap > 1 时都是预排序,⽬的是让数组更接近于有序。当 gap == 1 时,数组已经接近有序 的了,这样就会很快。这样整体⽽⾔,可以达到优化的效果。
希尔排序的时间复杂度计算

希尔排序的时间复杂度估算: 外层循环: 外层循环的时间复杂度可以直接给出为: O (log 2 n ) 或者 O (log 3 n ) ,即 O (log n ) 内层循环: https://i-blog.csdnimg.cn/direct/cd2630da42ab4dcaa08d577aa49eddb0.png 假设⼀共有n个数据,合计gap组,则每组为n/gap个;在每组中,插⼊移动的次数最坏的情况下为 https://i-blog.csdnimg.cn/direct/28c0ab3061254c31852275e712644585.png ⼀共是gap组,因此: 总计最坏情况下移动总数为: https://i-blog.csdnimg.cn/direct/6d19cf552fce40b8bdfd952a1a8e990b.png gap取值有(以除3为例):n/3 n/9 n/27 …… 2 1 • 当gap为n/3时,移动总数为: https://i-blog.csdnimg.cn/direct/13d7abc2e0cd4373a435a00a0bc546e2.png • 当gap为n/9时,移动总数为: https://i-blog.csdnimg.cn/direct/399b5f96326e481ea2deab30c50c91f8.png • 最后⼀躺,gap=1即直接插⼊排序,内层循环排序消耗为n 因此,希尔排序在最初和最后的排序的次数都为n,即前⼀阶段排序次数是逐渐上升的状态,当到达某⼀顶点时,排序次数逐渐下降⾄n,⽽该顶点的计算暂时⽆法给出具体的计算过程

  • 希尔排序时间复杂度不好计算,因为 gap 的取值很多,导致很难去计算,因此很多书中给出的希尔排序的时间复杂度都不固定。《数据结构(C语⾔版)》— 严蔚敏书中给出的时间复杂度为: https://i-blog.csdnimg.cn/direct/a5bec444cf1c42d08615ddd330736b1d.png

2.3直接选择排序

  1. 在元素集合 array[i]–array[n-1] 中选择关键码最⼤(⼩)的数据元素
  2. 若它不是这组元素中的最后⼀个(第⼀个)元素,则将它与这组元素中的最后⼀个(第⼀个)元素交换
  3. 在剩余的 array[i]–array[n-2](array[i+1]–array[n-1]) 集合中,重复上述步骤,直到集合剩余 1 个元素 void SlelectSort(int* arr, int n) { int begin = 0; int end = n - 1; while (begin < end) { int min = begin, max = begin; for (int i = begin + 1; i <= end; i++) { if (arr[i] < min) { min = i; } if (arr[i] > max) { max = i; } } if (max = begin) { max = min; } Swap(&arr[min], &arr[begin]); Swap(&arr[max], &arr[end]); begin++; end–; } } https://i-blog.csdnimg.cn/direct/8f444ba626244d539363ef02cddc5139.png https://i-blog.csdnimg.cn/direct/30ad8c0356a44da1845469a4f202aa56.png 直接选择排序的特性总结:
  4. 直接选择排序思考⾮常好理解,但是效率不是很好。实际中很少使⽤
  5. 时间复杂度: O(N 2 )
  6. 空间复杂度: O(1) 未完待续~~~