码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 【数据结构取经之路】希尔排序


    目录

    引言

    思想

    动图

    过程展开图

     gap的取值

    时间复杂度

    空间复杂度

    代码及其解释


    引言

    希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因 D.L.Shell 于 1959 年提出而得名。

    思想

     希尔排序是把原数组按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的元素越来越多,当增量减至 1 时,整个数组恰被分成一组,算法便终止。 

    换种说法,希尔排序是先将整个待排数组分割成若干个子数组,再对子数组分别进行直接插入排序,使整个数组趋近于有序,再对整个数组进行一次直接插入排序。 

    可以总结其步骤为:

    一、用直接插入排序进行预排序——接近有序

    二、直接插入排序

    动图

    过程展开图

    图中颜色相同的为一组。

    间隔为gap的分为一组,总计gap组。 

    动态计算增量gap。

    从上述过程可以看到,希尔排序的一个特点是:子数组的构成不是简单的“逐段分割”,而是将相隔某个增量(gap)的元素组成一个子数组。相较于直接插入排序,当gap不等于1时,元素不是一步一步的挪动的,而是跳跃式的移动,从而使得在进行最后一趟增量gap = 1的插入排序时,数组已基本有序,只要少量移动和比较即可完成排序。因此希尔排序较直接插入排序的时间复杂度低。

     gap的取值

    在希尔排序中,增量的取值决定了分组的大小以及排序的效率。一般增量的取值有以下两种:

    gap = gap / 2

    gap = gap / 3 + 1

     确保最后一个增量的值为1。

    时间复杂度

    希尔排序的分析是一个复杂的问题,因为它的时间是所取“增量”序列的函数,这涉及到一些数学上尚未解决的难题。但有人在大量实验的基础上推出:当n在某个特定范围内,希尔排序所需的比较和移动次数约为n^1.3,所以希尔排序的时间复杂度为O(n^1.3)。

    空间复杂度

    希尔排序是一种原地排序算法,所以空间复杂度为O(1)。

    代码及其解释

    1. #include
    2. void Print(int* a, int n)
    3. {
    4. for (int i = 0; i < n; i++) printf("%d ", a[i]);
    5. printf("\n");
    6. }
    7. void ShellSort(int* a, int n)
    8. {
    9. int gap = n;
    10. while (gap > 1)
    11. {
    12. gap = gap / 3 + 1;//动态调整gap
    13. for (int i = 0; i < n - gap; i++)//多组并排
    14. {
    15. int end = i;
    16. int tmp = a[end + gap];
    17. while (end >= 0)
    18. {
    19. if (tmp < a[end])
    20. {
    21. a[end + gap] = a[end];
    22. end -= gap;
    23. }
    24. else
    25. {
    26. break;
    27. }
    28. }
    29. a[end + gap] = tmp;
    30. }
    31. }
    32. }
    33. int main()
    34. {
    35. int a[] = { 5,1,3,8,0,2,6,4,7 };
    36. int n = sizeof(a) / sizeof(int);
    37. Print(a, n);
    38. ShellSort(a, n);
    39. Print(a, n);
    40. return 0;
    41. }

    对多组并排的解释:

    下图中,颜色相同的为一组。

    为了说明清楚多组并排,这里拿非多组并排来作为对比。 如果是非多组并排,那么在进行第一趟希尔排序时,就会将粉红色数组中的四个元素看做一个整体进行插入排序,得到的结果为:0 3 6 9。而多组并排呢,是先对9和6进行插入排序得到6 9,接着对下一组(蓝色数组)的8和5进行插入排序,并不是一次性将蓝色数组排好序得到2 5 8,而是不同组之间交替的进行部分插入排序。

  • 相关阅读:
    No module named ‘torch.distributed.checkpoint.format_utils问题解决
    DeepSpeed: 大模型训练框架 | 京东云技术团队
    电力电子转战数字IC20220825day69——MCDF更新APB总线
    Java 线程安全的集合有哪些?
    面试题:在大型分布式系统中,给你一条 SQL,让你优化,你会怎么做?
    【多式联运】基于matlab改进的模拟退火优化遗传算法求解多式联运运输问题(含碳政策)【含Matlab源码 1995期】
    【基于pyAudioKits的Python音频信号处理(四)】傅里叶变换:从时域到频域
    27K测试老鸟6年经验的面试心得,四种公司、四种问题…
    Zfile-轻量开源个人网盘【超简单部署】
    ZZNUOJ_用C语言编写程序实现1342:支配值数目(附完整源码)
  • 原文地址:https://blog.csdn.net/bit_pan/article/details/136737847
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号