[4] 算法之路 - 插入排序之Shell间隔与Sedgewick间隔

本文介绍Shell排序法的基本原理及其两种不同间隔序列的应用:n/2间隔和Sedgewick间隔。通过对比这两种间隔序列,文章详细阐述了如何通过优化间隔序列来提高排序效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

插入排序法由未排序的后半部前端取出一个值,插入已排序前半部的适当位置。概念简单但速度不快。

 排序要加快的基本原则之中的一个

是让后一次的排序进行时尽量利用前一次排序后的结果以加快排序的速度Shell排序法即是基于此一概念来改良插入排序法

解法

Shell排序法最初是D.L Shell于1959所提出,如果要排序的元素有n个。则每次进行插入排序时并非全部的元素同一时候进行时。而是取一段间隔。

 

Shell排序算法 – n/2间隔

Shell首先将间隔设定为n/2。然后跳跃进行插入排序。再来将间隔n/4。跳跃进行排序动作,再来间隔设定为n/8n/16,直到间隔为1之后的最后一次排序终止。


Shell排序算法 – Sedgewick间隔

 

将间隔设定为n / 2是D.L Shell最初所提出。在教科书中使用这个间隔比較好说明,然而Shell排序法的关键在于间隔的选定。比如Sedgewick证明选用下面的间隔能够加 快Shell排序法的速度:


e.g 对于一个长度为10000的整型数组。

Swedge[0]=10000, Swedge[1]=2537, Swedge[2]=653, Swedge[4]=48,Swedge[5]=15…Swedge[8]=1

採用Swedge间隔须要迭代8次 (Swedge[0] 不使用)

而用普通Shell间隔须要迭代13次

Comsh [0]=10000, Comsh [1]=5000, Comshe[2]=2500, Comsh[4]=625,…..Comshell[8]=39, Comshell[13]=1


后来还有人证明有其他的间隔选定法能够将Shell排序法的速度再加快;另外Shell排序法的概念也能够用来改良气泡排序法。


SourceCodes


n/2间隔与Sedgewick间隔的 Shell排序


int DLShellSort(int a[],int lens)
{
	for(int gap=lens/2;gap>0;gap/=2)
	{
		InsertionSortWithGap(a,lens,gap);
	}
	return 0;
}

// 4*((2^j)^2)+3*(2^j)+1<=n
// j= log(((-3+sqrt(16*lens-7.0))/8))/log(2.0)
int SedgewickShellSort(int a[],int lens)
{
	int sdwindex= (int)log(((-3+sqrt(16*lens-7.0))/8))/log(2.0);
	int sdwpr=(int)pow(2,(double)sdwindex);
	int sdwpr2=sdwpr/2;
	while(true)
	{
		int sdwgap=4*sdwpr2*sdwpr2+3*sdwpr2+1;
		InsertionSortWithGap(a,lens,sdwgap);
		sdwpr2/=2;
		if(sdwpr2<=1)break;
	}
	return 0;
}


见 [3] 算法之路 - 插入排序
// 插入排序 使用指定间隔的
int InsertionSortWithGap(int a[],int lens,int gap)
{
	int k,tmp;
	// 控制插入层
	for(int m=0;m<gap;m++)
	{
		for(int i=gap+m;i<lens;i+=gap)
		{
			int j=i-gap;
			tmp=a[i];
			for(k=j;k>=0;k-=gap)
			{
				if(tmp<a[k]) a[k+gap]=a[k];
				else break;
			}
			if(i!=(k+gap))a[k+gap]=tmp;
		}
	}
	return 0;
}




转载于:https://www.cnblogs.com/claireyuancy/p/6806777.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值