• 数据结构------排序1


    目录

    1.什么是排序?

    2.直接插入排序 

    2.1多趟实现

    2.11实现原理

     2.12代码实现

    2.2时间复杂度计算 

    3.希尔排序

    3.1实现原理:

    3.2预排序

    3.21单趟实现

     3.22一组gap实现

     3.23整体实现(多组gap实现)

    3.3预排序的实现


    1.什么是排序?

    排序是计算机的一种操作方法,其目的是将一组“无序”的记录序列调整为“有序”的记录序列,主要分为内部排序和外部排序。

    若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序。反之,若参加排序的记录数量很大,整个序列的排序过程不可能在内存中完成,则称此类排序问题为外部排序。内部排序的过程是一个逐步扩大记录的有序序列长度的过程。

    2.直接插入排序 

    2.1多趟实现

    2.11实现原理

    如下图,插入排序的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。它在实现上,通常采用in-place排序(即只需用到的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

     2.12代码实现

    1. void InsertSort(int* a, int n)
    2. {
    3. int i ;
    4. for (i = 0; i < n - 1; i++)
    5. {
    6. int end = i;
    7. int tmp = a[end + 1];
    8. //end后一位
    9. while (end >= 0)
    10. {
    11. if (tmp < a[end])
    12. {
    13. a[end+1] = a[end ];
    14. end--;
    15. //因为插入这个数不仅和后边的数比较,还要大于前面的数,
    16. //所以end范围要缩小
    17. }
    18. else
    19. //这一步有两种第一种是比较好了,
    20. //第二种是要插入的数小于所有数。直接结束
    21. {
    22. break;
    23. }
    24. }
    25. a[end + 1] = tmp;
    26. }
    27. }

    2.2时间复杂度计算 

    3.希尔排序

    3.1实现原理:

    希尔排序是将待排序的数组元素 按下标的一定增量分组(gap) ,分成多个子序列,然后对各个子序列进行直接插入排序算法排序; 然后依次缩减增量再进行排序,直到增量为1时,进行最后一次直接插入排序,排序结束。”

     实际意思是例如上面的11个数,我们可以按增量gap为3分组(gap<11),分成了1, 4, 7, 11;2, 5, 8, 12;还剩下3, 6, 9三个,虽然不满4个,但是我们也把它分为一组。然后把这三组数的每一组数都从大到小排列,然后三组继续按照它原来下标位置,将数排列,最后整体在排列。

    3.2预排序

    先把无序数组大致排成一个升序数组

     这就是预排序,数组已经大差不差有一个升序的样子,但是个别数顺序要改一下。

    3.21单趟实现

     3.22一组gap实现

     3.23整体实现(多组gap实现)

    1. void ShellSort(int* a, int n)
    2. {
    3. int i = 0;
    4. int gap=3;
    5. for (int j = 0; j < gap; j++)
    6. {
    7. for (i = 0; i < n - gap; i += gap)
    8. //i<倒数第二个数据即可,最后一个和倒数第二个直接比较
    9. {
    10. int end = i;
    11. int tmp = a[end + gap];
    12. //end的后一位
    13. while (end >= 0)
    14. {
    15. if (tmp < a[end])
    16. {
    17. a[end + gap] = a[end];
    18. end -= gap;
    19. }
    20. else
    21. {
    22. break;
    23. }
    24. }
    25. a[end + gap] = tmp;
    26. }
    27. }

    3.3预排序的实现

    接下来就是微调和怎样确定gap。

    1. void ShellSort(int* a, int n)
    2. {
    3. int i = 0;
    4. while (gap > 1)
    5. {
    6. gap = gap / 3 + 1;//缩小gap范围,+1,保证最后gap范围
    7. //不为0,还可以计算
    8. for (i = 0; i < n - gap; ++i) //先算后加i
    9. {
    10. int end = i;
    11. int tmp = a[end + gap];
    12. while (end >= 0)
    13. {
    14. if (tmp < a[end])
    15. {
    16. a[end + gap] = a[end];
    17. end -= gap;
    18. }
    19. else
    20. {
    21. break;
    22. }
    23. }
    24. a[end + gap] = tmp;
    25. }
    26. }
    27. }

    这个++i,相当于在最后源码最后面是i++, 

     为啥上面的最外层for循环省略了?

    ++i就可以是i从第一gap组比较完移到第二等组,所以就少一循环。

     为啥gap要有一组循环?

    注意预排不是只有一组,要进行好多组。

  • 相关阅读:
    Covalent Network(CQT)构建 Web3 最大的结构化数据集,开拓AI、安全性和数据质量的融合
    numpy的基础操作
    IPIDEA的使用方式
    Elasticsearch优化
    vuex怎么防止数据刷新丢失?
    linux os cpufreq 调频
    项目3-食物图片分类
    linux内核分析:进程与调度
    pandas 使用 isin 判断 字符是否在列表中的方法提示错误的解决方法
    linux PELT算法中的load计算
  • 原文地址:https://blog.csdn.net/bit_jie/article/details/125934878