• 基本算法-希尔排序


    作者:翟天保Steven
    版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处


    前言

           本文介绍一种排序算法——希尔排序,是常用的排序算法之一。以下是本篇文章正文内容,包括算法简介、算法特点、算法实现和C++示例。

    一、希尔排序简介

           希尔排序法是一种改进版的插入排序。众所周知,插入排序在排序的过程中要一个个向前比较,这样耗费了大量的时间,比如一个最小值插入到最前排,要进行n-1次比较,那如果有一种方法能让其大步伐跨越并快速到达指定位置,不就能大幅缩短排序时间了嘛,希尔排序就干了这么件事。

           希尔排序也可以称为增量递减排序,核心理念就是让数值先以较大的增量快速靠近目标位置,比如共n个数值,起始增量可以设为n/2,这样一个最小值到第一个位置,第一步就跨越了数据集的一半,这比一个个往前插可快多了;随后,增量再递减为n/4,以此类推;等增量递减为1了,数据集就相当于再执行一次常规的插入排序,且这次排序本身就基本排好了,最多只需要和左右交换一下即可。

    二、算法特点

           1)时间复杂度与增量的选取相关。

           2)稳定性与增量选取相关。

           3)只需要一个额外空间,空间复杂度很低。

           4)此排序法适用于大部分数据已经排过序的情况。

    三、代码实现

           代码实现逻辑:

    1. jump为步进增量,增量每次除以2来完成缩小,增量为0时完成排序。
    2. 以jump为增量进行插入排序,和常规插入排序一样,只不过步进量改变了。
    3. 若result[j]>result[i],则进入while循环,这个循环干的事就是把比当前数大的值都往后排,所以有result[j+jump]=result[j]和j-=jump的操作;到了某个位置,当前数大于前一个数了,此时循环终止,将之前存的temp赋值在当前位置上,就相当于将其插入了。
    1. // 希尔排序
    2. vector<int> ShellSort(vector<int> data)
    3. {
    4. // 拷贝
    5. vector<int> result = data;
    6. // 排序过程:
    7. // jump表示步进量,相较插入排序而言,希尔排序可以让较小的数值以较大的步子快速接近目标位
    8. int size = static_cast<int>(data.size());
    9. int jump = size / 2;
    10. while (jump != 0)
    11. {
    12. // 以jump为步进量,进行插入排序
    13. for (int i = jump; i < size; ++i)
    14. {
    15. int temp = result[i];
    16. int j = i - jump;
    17. while (result[j] > temp && j >= 0)
    18. {
    19. result[j + jump] = result[j];
    20. j -= jump;
    21. }
    22. result[j + jump] = temp;
    23. }
    24. // 缩小步进量,当步进量为0时,即完成排序
    25. jump /= 2;
    26. }
    27. return result;
    28. }

    四、C++示例

    1. #include <iostream>
    2. #include <iomanip>
    3. #include <vector>
    4. #include <string>
    5. using namespace std;
    6. // 展示当前顺序
    7. void Show(vector<int> data)
    8. {
    9. size_t size = data.size();
    10. for (size_t i = 0; i < size; ++i)
    11. cout << setw(4) << data[i];
    12. cout << endl;
    13. }
    14. // 希尔排序
    15. vector<int> ShellSort(vector<int> data)
    16. {
    17. // 拷贝
    18. vector<int> result = data;
    19. cout << "希尔排序:\n原始数据:\n";
    20. Show(result);
    21. // 排序过程:
    22. // jump表示步进量,相较插入排序而言,希尔排序可以让较小的数值以较大的步子快速接近目标位
    23. int size = static_cast<int>(data.size());
    24. int jump = size / 2;
    25. int k = 1;
    26. while (jump != 0)
    27. {
    28. // 以jump为步进量,进行插入排序
    29. for (int i = jump; i < size; ++i)
    30. {
    31. int temp = result[i];
    32. int j = i - jump;
    33. while (result[j] > temp && j >= 0)
    34. {
    35. result[j + jump] = result[j];
    36. j -= jump;
    37. }
    38. result[j + jump] = temp;
    39. }
    40. cout << "第" << k << "次排序结果:\n";
    41. Show(result);
    42. k++;
    43. // 缩小步进量,当步进量为0时,即完成排序
    44. jump /= 2;
    45. }
    46. cout << "排序后结果:\n";
    47. Show(result);
    48. return result;
    49. }
    50. // 主函数
    51. int main()
    52. {
    53. vector<int> data = { 9,11,567,0,-2,4,2 };
    54. // 希尔排序
    55. vector<int> result4 = ShellSort(data);
    56. system("pause");
    57. return 0;
    58. }

           效果图:

           综上所述,希尔排序法是个比较好用的排序法,优点是相较插入排序,它的插入速度更快,缺点就是对那些已经排序完毕的数组,也要将不同增量都遍历一遍~

           如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

  • 相关阅读:
    实用工具系列 - Pycharm插件推荐
    高项_第十四章信息文档管理与配置管理
    备份数据库及删除三天前备份记录
    CS224W 7 A General Perspective on Graph Neural Networks
    有哪些适合程序员做的副业?
    【无标题】
    最新版的Python写春联,支持行书隶书楷书,不再有缺失汉字
    半导体CIM系统中的EAP:提升制造效率的关键
    flowable
    17 【2D转换 3D转换 浏览器私有前缀】
  • 原文地址:https://blog.csdn.net/zhaitianbao/article/details/125613078