最优时间复杂度为o(n),又称缩小增量排序。

逻辑分析:

1、希尔排序首先是确定增量,默认的希尔增量(不一定是最优)为length/2。

2、根据增量分组,将分组的元素利用直接插入法排序。

3、增量=增量/2,再次分组,一直到增量为1为止。

通过上述步骤我们可以知道,代码会有3个循环,第一个gap的更新,即for(int gap=len/2;gap>0;gap/=2)。第二个和第三个循环是对分组数组进行直接插入排序。

代码分析:

数组a[] = { 2,1,4,5,3,8,7,9,0,6 },length=10。

第一次大循环

gap=length/2=5,i=5,j=i-gap=0,a[j]=2<a[j+gap]=8,此时数组不做任何操作。

gap=length/2=5,i=6,j=i-gap=1,a[j]=1<a[j+gap]=7,此时数组不做任何操作。

gap=length/2=5,i=7,j=i-gap=2,a[j]=4<a[j+gap]=9,此时数组不做任何操作。

gap=length/2=5,i=8,j=i-gap=3,a[j]=5<a[j+gap]=0,故交换a[j]和a[j+gap],数组a[]= { 2,1,4,0,3,8,7,9,5,6 }。

gap=length/2=5,i=9,j=i-gap=4,a[j]=3<a[j+gap]=6,此时数组不做任何操作。

第二次大循环

gap=gap/2=2,i=2,j=i-gap=0,a[j]=3<a[j+gap]=4,此时数组不做任何操作。

gap=gap/2=2,i=3,j=i-gap=1,a[j]=1>a[j+gap]=0,故交换a[j]和a[j+gap],数组a[]= { 2,0,4,1,3,8,7,9,5,6 }。

gap=gap/2=2,i=4,j=i-gap=2,a[j]=4>a[j+gap]=3,故交换a[j]和a[j+gap],数组a[]= { 2,0,3,1,4,8,7,9,5,6 }。

gap=gap/2=2,i=4,j=i-gap=0,a[j]=2<a[j+gap]=3,此时数组不做任何操作。

gap=gap/2=2,i=5,j=i-gap=3,a[j]=1<a[j+gap]=8,此时数组不做任何操作。

gap=gap/2=2,i=6,j=i-gap=4,a[j]=4<a[j+gap]=7,此时数组不做任何操作。

gap=gap/2=2,i=7,j=i-gap=5,a[j]=8<a[j+gap]=9,此时数组不做任何操作。

gap=gap/2=2,i=8,j=i-gap=6,a[j]=7>a[j+gap]=5,故交换a[j]和a[j+gap],数组a[]= { 2,0,3,1,4,8,5,9,7,6 }。

gap=gap/2=2,i=9,j=i-gap=7,a[j]=9>a[j+gap]=6,故交换a[j]和a[j+gap],数组a[]= { 2,0,3,1,4,8,5,6,7,9 }。

第三次大循环

gap=gap/2=1,i=1,j=i-gap=0,a[j]=2>a[j+gap]=0,故交换a[j]和a[j+gap],数组a[]= { 0,2,3,1,4,8,5,6,7,9 }。

gap=gap/2=1,i=2,j=i-gap=1,a[j]=2<a[j+gap]=3,此时数组不做任何操作。

gap=gap/2=1,i=3,j=i-gap=2,a[j]=3>a[j+gap]=1,故交换a[j]和a[j+gap],数组a[]= { 0,2,1,3,4,8,5,6,7,9 }。

gap=gap/2=1,i=3,j=j-gap=1,a[j]=2>a[j+gap]=1,故交换a[j]和a[j+gap],数组a[]= { 0,1,2,3,4,8,5,6,7,9 }。

gap=gap/2=1,i=3,j=j-gap=0,a[j]=0<a[j+gap]=1,此时数组不做任何操作。

gap=gap/2=1,i=4,j=i-gap=3,a[j]=3<a[j+gap]=4,此时数组不做任何操作。

gap=gap/2=1,i=5,j=i-gap=4,a[j]=4<a[j+gap]=8,此时数组不做任何操作。

gap=gap/2=1,i=6,j=i-gap=5,a[j]=8>a[j+gap]=5,故交换a[j]和a[j+gap],数组a[]= { 0,1,2,3,4,5,8,6,7,9 }。

gap=gap/2=1,i=6,j=j-gap=4,a[j]=4<a[j+gap]=5,此时数组不做任何操作。

gap=gap/2=1,i=7,j=i-gap=6,a[j]=8>a[j+gap]=6,故交换a[j]和a[j+gap],数组a[]= { 0,1,2,3,4,5,6,8,7,9 }。

gap=gap/2=1,i=7,j=j-gap=5,a[j]=5<a[j+gap]=6,此时数组不做任何操作。

gap=gap/2=1,i=8,j=i-gap=7,a[j]=8>a[j+gap]=7,故交换a[j]和a[j+gap],数组a[]= { 0,1,2,3,4,5,6,7,8,9 }。

gap=gap/2=1,i=8,j=j-gap=6,a[j]=6<a[j+gap]=7,此时数组不做任何操作。

gap=gap/2=1,i=9,j=i-gap=8a[j]=8<a[j+gap]=9,此时数组不做任何操作。

排序完成,输出数组a[]= { 0,1,2,3,4,5,6,7,8,9 }。

#include<iostream>
#include<cstdlib>using namespace std;//交换
void swap(int &a, int &b)
{int temp = a;a = b;b = temp;
}//希尔排序,首先根据增量分组,然后对分组元素进行直接插入排序
void shellSort(int a[],  int length)
{for (int gap = length/2; gap>0; gap/=2){for (int i = gap; i<length;++i){for (int j = i - gap; j >=0 && a[j] > a[j + gap]; j -= gap){swap(a[j], a[j + gap]);}}}}int main()
{int a[] = { 2,1,4,5,3,8,7,9,0,6 };shellSort(a, 10);for (int i = 0; i < 10; i++){cout << a[i] << "";}cout << endl;system("pause");return 0;}

发现上述代码真的有好多重复的地方,加了一个标志,来改进一下

#include<iostream>
#include<cstdlib>using namespace std;void swap(int &a, int &b)
{int temp = a;a = b;b = temp;
}void shellSort(int a[],  int length)
{for (int gap = length/2; gap>0; gap/=2){for (int i = gap; i<length;++i){bool action = true;for (int j = i - gap; j >=0 && action; j -= gap){if (a[j] > a[j + gap]){swap(a[j], a[j + gap]);}else  action = false;}}}}int main()
{int a[] = { 65,44,77,5,24,89,72,58,40,69 };shellSort(a, 10);for (int i = 0; i < 10; i++){cout << a[i] << " ";}cout << endl;system("pause");return 0;}

插入排序 希尔排序 C++相关推荐

  1. 【排序算法】冒泡排序|选择排序|插入排序|希尔排序

    文章目录 冒泡排序 选择排序 插入排序 希尔排序 冒泡排序   第一个元素开始向第二个元素比较,若大于则交换位置,不大于则不动.然后第二个元素和第三个元素比较,再然后第三个元素和第四个元素比较-一直比 ...

  2. 直接插入排序 希尔排序 冒泡排序 快速排序 直接选择排序 堆排序 归并排序 基数排序的算法分析和具体实现 ...

    排序分为内部排序和外部排序 内部排序是把待排数据元素全部调入内存中进行的排序. 外部排序是因数量太大,把数据元素分批导入内存,排好序后再分批导出到磁盘和磁带外存介质上的排序方法. 比较排序算法优劣的标 ...

  3. 插入排序(折半查找优化插入排序||希尔排序) _清风明月

    插入排序:插入排序分为三个步骤: 1. 找位置.(序列可分为两个部分,第一个部分是有序序列,其二是非有序序列.当为有序序列时,查找可以改进为折半查找,优化算法速度.) 2. 移动. 3. 插入.查找的 ...

  4. 【Java】5大排序算法总结(插入排序+希尔排序+选择排序+堆排序+冒泡排序)

    快速导航: 1. 稳定性 2 . 插入排序 3. 希尔排序 4. 选择排序 5. 堆排序 6 冒泡排序 1. 稳定性 两个相等的数据,如果经过排序后,排序算法能保证其相对位置不发生变化,则我们称该算法 ...

  5. 插入排序--希尔排序

    希尔排序,又称为""缩小增量排序"",他的实质是采用分组插入的方法,将整个数组分为几组,从而减少插入排序的数据量,将每组的两端的元素进行比较,然后交换,然后缩小 ...

  6. 【排序算法】冒泡排序 选择排序 插入排序 希尔排序(数组)

    冒泡排序 #include<iostream> using namespace std; #define SWAP(a,b) {int tmp;tmp=a;a=b;b=tmp;} int ...

  7. 插入排序:直接插入排序希尔排序

    一.直接插入排序 1. 思想 直接排序法, 可以分为两个部分, 一部分是有序的, 一部分是无序的. 从这个图上, 应该是能看清楚直接插入排序的思想了. 将无序部分的第一个与有序部分进行比较. 从有序部 ...

  8. 王道八大排序:直接插入排序 折半插入排序 希尔排序 冒泡排序 快速排序 归并排序 基数排序

    文章目录 1.插入排序 1.1直接插入排序 1.2折半插入排序 1.3希尔排序 2.交换排序 2.1冒泡排序 2.2快速排序 3.选择排序 3.1简单选择排序 3.2堆排序 4.归并排序 5.基数排序 ...

  9. 数据结构(八):排序 | 插入排序 | 希尔排序 | 冒泡排序 | 快速排序 | 简单选择排序 | 堆排序 | 归并排序 | 基数排序 | 外部排序 | 败者树 | 置换-选择排序 | 最佳归并树

    文章目录 第八章 排序 一.排序的基本概念 (一)什么是排序 (二)排序的应用 (三)排序算法的评价指标 (四)排序算法的分类 (五)总结 二.插入排序 (一)算法思想 (二)算法实现 (三)算法效率 ...

最新文章

  1. snmp Oid整理与运用
  2. Linux shell 自启动脚本写法
  3. Codeforces Round #504 E - Down or Right 交互题
  4. [手把手教]discuzX2插件制作教程__最菜鸟级别的入门坎 【二】
  5. 搭建cacti监控平台
  6. python数据挖掘视频_python+opencv实时视频目标检测
  7. 华为云全球首发企业级AI应用开发套件ModelArts Pro,加速行业AI落地
  8. oracle中序号生成器,Oracle序列生成器
  9. 南大电子机器人入驻云南_园区优秀企业| 中科恒清清淤机器人,以智能科技为水环境治理保驾护航...
  10. 如何在传统 ASP 和 ASP.NET 之间共享会话状态
  11. Android eclipse unable to launch:The selection can not be launched,and there are no recent launches
  12. oracle语句_ORACLE 常用语句实例:CTE MERGE 结合
  13. 王者服务器维护11月,11月17日体验服停机更新公告
  14. 什么是集群负载均衡与高可用(有图详解)
  15. 数据库系统概论(各章知识点总结)
  16. linux xp双系统引导修复工具,双系统xp和linux xp重装后修复linux引导光盘修复方法...
  17. DC学院数据分析师(入门)学习笔记----高级爬虫技巧
  18. 【Practical】共轭
  19. 虚拟空间对新闻媒体的真实挑战
  20. 全国大学生智能车竞赛2022年-智能汽车竞赛发展沙龙

热门文章

  1. linux nginx线程池,nginx使用线程池提升9倍性能
  2. vc++ 提取网页上的文字_网页内容不让你复制?老师傅教的这招太绝了,1键提取全网文字...
  3. 装服务器显示磁盘脱机,服务器磁盘处于脱机
  4. python中的标识符能不能使用关键字_Python中的标识符不能使用关键字
  5. python打包库_Python 打包自己的库到 PYPI (可pip安装)
  6. 没有什么是日本牛郎店做不到的......
  7. 人体的血管连起来竟能绕地球两圈!?| 今日最佳
  8. 兵马未至,数据先行,且看如何进行数据挖掘!
  9. 74款app源码,值得你拥有的干货
  10. Android 页面布局xd,Adobe XD强大的布局系列工具 助你事半功倍