【排序算法】直接插入排序与希尔(Shell)排序

希尔排序算法代码详解(附插入排序代码) 1959年Shell发明,第一个突破O(n2)的排序算法,是直接插入排序的改进版。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。 希尔排序的大致思路是把数组的元素按照一定的间隔进行逻辑分组,分组后针对每一组进行插入排序。并且渐渐减小间隔,随着间隔的缩小,整个数组就变得越来越有序。这个间隔叫做希尔增量。 希尔排序的时间复杂度难以测算,大概是O(n^(1.3—2))这么一个范围。希尔排序是一种不稳定的排序算法。 下面是希尔排序的代码演示,所有的注释都在代码里。 为了辅助理解 阅读详情

直接插入排序 是依次将每个元素插入到一个有序的序列当中去,可以用抓扑克牌来类比,实现如下:

/*插入排序*/
void insert_sort(int Array[],int Len)
{
	//可以用抓扑克牌类似
  int temp=0,j=0;
 for(int i=1;i<Len;i++)
 {      temp=Array[i];
        j=i-1;
		while(j>=0&&temp<=Array[j])
        {
             Array[j+1]=Array[j];
			 j--;
        }
        Array[j+1]=temp;
 }
}
插入排序算法是稳定的,最坏情况时间复杂度为:O(n^2),最好为:O(n),平均情况:O(n^2)
希尔排序:希尔排序(Shell Sort)又称为缩小增量排序,输入插入排序算法,是对直接排序算法的一种改进。

 希尔排序是基于插入排序的以下两点性质而提出改进方法的:

    1)插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率

    2)但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位

2、算法思想 

    希尔排序通过将比较的全部元素分为几个区域来提升插入排序的性能。这样可以让一个元素可以一次性地朝最终位置前进一大步。然后算法再取越来越小的步长进行排序,算法的最后一步就是普通的插入排序,但是到了这步,需排序的数据几乎是已排好的了(此时插入排序较快)。

    假设有一个很小的数据在一个已按升序排好序的数组的末端。如果用复杂度为O(n^2)的排序(冒泡排序或插入排序),可能会进行n次的比较和交换才能将该数据移至正确位置。而希尔排序会用较大的步长移动数据,所以小数据只需进行少数比较和交换即可到正确位置。

    一个更好理解的希尔排序实现:将数组列在一个表中并对列排序(用插入排序)。重复这过程,不过每次用更长的列来进行。最后整个表就只有一列了。将数组转换至表是为了更好地理解这算法,算法本身仅仅对原数组进行排序(通过增加索引的步长,例如是用i += step_size而不是i++)。

    数学表述为先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。

    该方法实质上是一种分组插入方法。

    例如,假设有这样一组数[ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ],如果我们以步长为5开始进行排序,我们可以通过将这列表放在有5列的表中来更好地描述算法,这样他们就应该看起来是这样:

    13 14 94 33 82

    25 59 94 65 23

    45 27 73 25 39

    10

    然后我们对每列进行排序:

    10 14 73 25 23

    13 27 94 33 39

    25 59 94 65 82

    45

    当我们以单行来读取数据时我们得到:[ 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 ].这时10已经移至正确位置了,然后再以3为步长进行排序:

    10 14 73

    25 23 13

    27 94 33

    39 25 59

    94 65 82

    45

    排序之后变为:

    10 14 13

    25 23 33

    27 25 59

    39 65 73

    45 94 82

    94

    最后以1步长进行排序(此时就是简单的插入排序了)。

3、算法实现

void ShellSort(int Array[],int n)
{
	int i,j,gap;
	int temp;
	gap=n/2; //增量初始值
	while(gap>=1)
	{
		for(i=gap;i<n;i++)//对所有相隔gap位置的所有元素进行插入排序
		{
			temp=Array[i];
			j=i-gap;
			while(j>=0&&temp<Array[j]) //对相隔gap位置的元素组进行排序
			{
				Array[j+gap]=Array[j];
				j=j-gap;
			}
			 Array[j+gap]=temp;
             j=j-gap;
		}
		 Display(Array,n);
		gap=gap/2;  //减少增量
	
	}
	
}
//输出数组
void Display(int array[],int length)


{
         for(int i =0;i<length;i++)


         {
                   cout<<array[i]<<", ";
         }


         cout<<endl;
}

主函数:

void main(int argc,char *argv[])
{
	
	int Array[]={5,4,8,9,3,2,10,6};
	int Len=sizeof(Array)/sizeof(int);
	ShellSort(Array,Len);
	 printf("排序好的数组为:");
	  Display(Array,Len);}



4、算法分析

     希尔排序是按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小,插入排序对于有序的序列效率很高。所以,希尔排序的时间复杂度会比o(n^2)好一些。

     最差时间复杂度   根据步长序列的不同而不同。 最坏的情况下复杂度为: O(nlog^2n)

     

     平均时间复杂度 : O(nlog^2n) 


    由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的

 



ALSA音频开发实战:如何用snd_pcm_avail避免缓冲区溢出(附完整代码) 本文深入探讨了在ALSA音频开发中,如何利用`snd_pcm_avail`函数有效管理环形缓冲区,从而避免音频数据溢出或下溢。通过实战代码示例,详细解析了该函数在播放场景下的核心作用,即实时查询可写入的帧数,并构建了自适应写入循环以实现稳健的流量控制,确保音频流的平滑与稳定。 阅读详情

相关推荐

Android 13/14/15 默认授权应用权限的实现方法

Android版本修改方式实现原理13/14修改Permission.java将所有权限标记为Normal权限15修改DeviceIdleController.java + DefaultPermissionGrantPolicy.java监听应用安装并主动授权。

m0_60898338的博客 2909

算法实现之直接插入排序与shell排序

1、直接插入排序 顾名思义,即直接以插入的方式排序,就是把原始数据分成两类:有序部分和无序部分,然后依次将无序部分的所有数据插入到有序部分。 由于遇到相等的数据,会把新插入的数据放在其后,所以,直接插入排序是稳定的。 void insertsort(int *a, int n) { for (int i = 1; i < n; i++) { if (a[i] < a[i - 1]

Benjamin1083的专栏 582

Python学习(一)

快速入门 1.Linux系统中是可以直接使用Python进行编程,具体如下: 进入Python:在linux的Terminal中输入 Python ,进入Python的命令行; 退出Python:在linux的Terminal中输入quit() 或 exit() 或 ctrl +d ,再回车,退出Python的命令行。 2.python的源程序就是一个特殊格式的文本文件,可以使用任意文本编辑软件做Python的开发。 3.Python程序的文件扩展名通常都是 .py。 4.执行Python程序的方式:在

SummerXRT的博客 1280

【数据结构与算法】——插入排序

有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法

梵高先生 955

从零构建虚幻引擎体积云:参数调优与性能平衡的艺术

本文深入探讨了在虚幻引擎中构建逼真体积云系统的关键技术,包括Sky Atmosphere、Volumetric Cloud和Exponential Height Fog三大核心组件的协同工作。重点解析了体积云材质的高级控制、光照阴影的物理模拟以及性能优化策略,帮助开发者在视觉效果与性能之间找到最佳平衡点。

weixin_29012677的博客 938

【大模型】Coze AI 智能体工作流从配置到使用实战详解

Coze 扣子智能体工作流从配置到使用实战详解

congge 1万+

70 个 Shell 脚本面试问题和答案

我们为您的面试准备选择了预期的 70 个 shell 脚本问题和答案。对于所有系统管理员来说,了解脚本或至少基础知识真的很重要,这反过来有助于在您的工作环境中自动执行许多任务。在过去的几年里,我们已经看到所有的 linux 工作规范都需要脚本技能。 1)如何将参数传递给脚本? ./脚本参数 示例:脚本将显示文件名 ./show.sh file1.txt cat show.sh #!/bin/bash cat $1 2)如何在脚本中使用参数? 第一个参数:$1,第二个参数:$2 示例:脚本

太极淘的博客 1万+

后仿真中《SDF反标必懂连载篇》之 <INTERCONNECT/IOPATH> 到底反标电路路径是哪里

对于SDF INTERCONNECT ENTRY 描述,我们在之前的文章有详解。读万卷书,行万里路。实践很重要。今天,搞一下SDF INTERCONNECT / IOPATH 延迟数据信息,究竟反标的是哪一路径延时?究竟在电路上一段段如何表现出延迟现象的呢?

那么菜的博客 2131

排序算法之——插入排序分析

前言 最简单的排序算法之一是插入排序(insertion sort)。 思路 插入排序的思路是这样的: 插入排序。由N-1趟排序完成,对于i=1到N-1趟,保证从位置0到位置i上的元素为已排序状态(但不保证已排序的值一定小于未排序的值)。 过程: 对于位置i,先把i位置的值保存起来,然后把i挖空。 依次与前一个位置比较,比较i-1到0位置上的元素; 若发现i对应的值小于某个位置的值,则将该位置的...

日积月累,天道酬勤 1585

【LLM技术全景】规模定律与模型演进:为什么模型越大越强?

规模定律性能 ∝ 参数量^N性能 ∝ 数据量^M性能 ∝ 计算量^L其中 N, M, L 是小于1的正数(通常0.05~0.15)关键观察损失与规模的关系呈幂律(不是线性,也不是对数)三个要素(参数、数据、计算)需要协调增长只增加其中一个要素,收益会边际递减规模定律(Scaling Law):1. 模型性能与参数量、数据量、计算量呈幂律关系2. Kaplan定律(2020):参数量是主要因素3. Chinchilla定律(2022):数据和参数同等重要,最优比例1:20。

专注:太空算力、AI infra、异构调度、大模型成本工程 494

机器人中的数值优化(十三)——QP二次规划

本系列文章主要是我在学习《数值优化》过程中的一些笔记和相关思考,主要的学习资料是深蓝学院的课程《机器人中的数值优化》和高立编著的《数值最优化方法》等,本系列文章篇数较多,不定期更新,上半部分介绍无约束优化,下半部分介绍带约束的优化,中间会穿插一些路径规划方面的应用实例

慕羽★的博客 2792

排序算法-插入排序(直接插入排序、Shell排序)

排序算法-插入排序一、直接插入排序二、Shell排序(希尔排序) 一、直接插入排序 视频讲解 基本思想: 将第一个元素看成一个有序子序列,再依次从第二个元素起逐个插入这个有序的子序列中。 一般情况下,在第i步上,将elem[i]插入到由elem[0]~elem[i-1]构成的有序子序列中。 平均时间复杂度:O(n^2) 代码实现(C++): template <class ElemType> void StraightInsertSort(ElemType elem[], int n) //操作

GTC的博客 638

反光柱定位算法实战03:VEnus代码解析和纯反光柱定位中的可改进方向

本文深入解析了开源框架VEnus的反光柱定位与建图实现流程,包括强度提取、聚类、数据关联、位姿优化等核心模块。同时指出其三大局限:匹配质量脆弱性、单一传感器依赖和地图扩展逻辑缺失,并提出改进方向:融合里程计/IMU数据、引入图优化后端、建立动态地图维护机制。该分析为基于反光柱的定位系统优化提供了实用参考,有助于提升工业场景下的定位鲁棒性和精确性。

Studying…… 520

排序算法之直接插入排序、二分排序、希尔(Shell)排序

排序算法(上) 直接插入排序: void InsertionSort(ElemType A[],int n) //插入排序 { int i, j; for (i = 2; i &amp;lt;= n; i++) {//依次遍历,A[0]不保存数据,A[1]一个数不用排序直接插入作为已经排好的数组的第一个值 //其实该算法A[0]也可以保存数据,只需要把当前要比较的值用一个变量暂存就行 if (...

a353042907的博客 739

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

shell中的排序算法

shell中的排序算法 冒泡排序法 类似旗袍上涌的动作,会将数据在数组中从小大大或者从大到小不断的向前移动。 基本思想: 冒泡排序的基本思想是对比相邻的两个元素值,如果满足条件就交换元素值,把较小的元素移动到数组前面,把大的元素移动到数组后面(也就是交换两个元素的位置),这样较小的元素就像气泡一样从底部上升到顶部。 算法思路 冒泡算法由双层循环实现,其中外部循环用于控制排序轮数,一般为要排序的数组长度减1次,因为最后一次循环只剩下一个数组元素,不需要对比,同时数组已经完成排序了。而内部循环主要用于对比数组中

weixin_44938203的博客 1950

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

“Shell“八大排序算法(冒泡排序 .直接插入排序 .直接选择排序 .希尔排序)

八大排序算法(冒泡排序.直接插入排序.直接选择排序.希尔排序)

Wanghwei17的博客 774

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

【Java数据结构与算法】希尔排序

希尔排序介绍及其实现

lolly1023的博客 728

排序算法总结(冒泡排序、简单选择排序、直接插入排序、希尔shell排序、快速排序、归并排序、基数排序)

四、排序(Sort Algorithm) 1、概念 排序的概念:排序是将一组数据按照指定的顺序进行排列的过程。 排序可以分为内部排序和外部排序,内部排序是将处理的所有数据都加载到内部存储器中进行排序。 若数据量过大,无法全部加载到内存中,需要借助于外部存储进行排序。 1.1、内部排序 插入排序 直接插入排序、希尔排序 选择排序 简单选择排序、堆排序 交换排序 冒泡排序、快速排...

Simon郎的博客 852

八大排序算法之四:希尔(shell)排序----直接插入排序的改进

算法思想: 希尔排序的实现思想: 希尔排序,也可以称为:缩小增量排序。 实际上,就是在直接插入排序的基础上进行优化,对于要进行插入排序的数组,先进行了分组,通过实现分组内的插入排序,让每一组数现在本组内实现有序。 然后,通过缩小增量gap(也叫步长)将分组数逐渐减小。 => 因为前面已经实现了:各个分组内的数有序,所以,即使分组的方法改变导致新形成的分组中的数有变化,但是新的分组中的数已经比最初的时候有序了。 => 对于新的分组内的数,进行插入排序。 ······ => 最终,当gap=

qq_47888755的博客 331

Java中常见的几种排序算法

本文主要记录了几种常见的排序算法的Java实现,如冒泡排序、快速排序、直接插入排序、希尔排序、选择排序等等。 在学数据结构与算法时的部分记录,感觉好难啊╮(╯▽╰)╭,还需继续努力。 更多文章欢迎访问我的个人博客–&amp;gt;幻境云图 1. 冒泡排序 将序列中所有元素两两比较,将最大的放在最后面。 将剩余序列中所有元素两两比较,将最大的放在最后面。 重复第二步,直到只剩下一个数。 /**...

探索云原生 6092

取文件 shell_Shell排序算法

一、Shell排序算法的介绍  希尔排序,也称递减增量排序算法,是直接插入排序算法的一种高速而稳定的改进版本。  希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。  先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行...

weixin_39628160的博客 119

希尔排序思路总结

希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因D.L.Shell于1959年提出而得名。 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一...

qq_34729246的博客 272

数据结构---希尔排序(Python)

希尔排序 希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因DL.Shell于1959年提出而得名。 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。 希尔排序过程 希尔排序的基本思想...

rongpeisheng666的博客 265

scau 数据结构实验6 各种排序算法大全 8638 8639 8640 8641 8642 8643 8644 8645 8646 直接插入排序 折半插入排序 希尔Shell排序 冒泡排序...

实现了scau实验6里面的各大排序

2401_87808951的博客 731

算法学习:希尔排序

希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,同时该算法是冲破O(n2)的第一批算法之一。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。 希尔排序是把记录按下表的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键...

RoiRoc的专栏 172

简单易懂排序算法(四)【希尔排序】

希尔排序是D.L.Shell于1959年提出来的一种排序算法,在这之前排序算法的时间复杂度基本都是O(n^2)的,希尔排序算法是突破这个时间复杂度的第一批算法之一。 希尔排序:是对直接插入排序进行的一种改进排序算法,采用跳跃分割的方法,将整个待排序列分割成若干个子序列,对这些子序列进行直接插入排序,使其得到的结果基本有序,然后再不断缩减分割的区间,使其完全有序 基本有序:就是小的关键字基本在前面...

小二笙的博客 1005
上一篇: 二叉树的创建以及遍历
下一篇: 【排序算法】直接选择排序(SelectSort)与冒泡排序(BubbleSort)
xiaoding133
博客等级 码龄19年 415粉丝 159原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值