数据结构 希尔排序(ShellSort) 详解 附C++代码实现:

 

目录

 

简介:

算法描述:

代码实现:

总结一下:


简介:

1959年Shell发明,第一个突破O(n2)的排序算法,是简单插入排序的改进版。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序

算法描述:

先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,具体算法描述:

  • 选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;
  • 按增量序列个数k,对序列进行k 趟排序;
  • 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

 

è¿éåå¾çæè¿°

代码实现:

#include<iostream>
#include<time.h>
#include<stdlib.h>
using namespace std;
#define range 10000

void myrandom(int a[],int len)
{
	srand((unsigned)  time(NULL));
	for(int i=0;i<len;i++)
	a[i]=rand()%range+1;
}
void shellSort(int a[],int len)
{
	int gap=len/2;  // gap为增量 
	int i,j;
	for(;gap>0;gap/=2)  // 每次除二,逐渐缩小增量。 
	{
		for(i=gap;i<len;i++)
		{
			int num=a[i];
			for(j=i-gap;j>=0&&a[j]>num;j-=gap)
			{
				a[j+gap]=a[j];
			}
			a[j+gap]=num;
		}
	}
}

int main()
{
	clock_t start,end;
	start=clock();
	freopen("out_arr.txt","r",stdin);
	freopen("out希尔排序.txt","w",stdout);
	int arr[range];
	int n=range;
	for(int i=0;i<n;i++)
	{
		scanf("%d",&arr[i]);
	}
	shellSort(arr,n);
	for(int i=0;i<n;i++)
	{
		printf("%5d ",arr[i]);
		if((i+1)%50==0)
		printf("\n");
	}

	end=clock();
	cout<<"希尔排序用时:"<<(float)(end-start)*1000.0/CLOCKS_PER_SEC<<"ms"<<endl; 
	return 0;
}

测试结果:

 

 

总结一下:

希尔排序的核心在于间隔序列的设定。既可以提前设定好间隔序列,也可以动态的定义间隔序列。

间隔序列也就是增量,但实现增量的缩小方法很多。上面代码仅找了一种简便的缩小方式。

希尔排序是不稳定的。它是第一个突破O(n2)的排序算法。

 

说点题外话,我暂时也不知道这些排序算法的差别,可能我的测试数据太小了,常常听我老师说好好学,打好基本功,就像建房子打好地基一样,基础好,后面省劲,现在需要的是静下心来打好基础,沉下来,沉下来,不能浮躁,不然以后你的boss,让你做某一方面的研究,你才发现你本科时没认真学,…………,在合适的年龄做最合适的事,方可无悔。

下午有点浮躁,给自己打点鸡血。O(∩_∩)O哈哈~

 

 

小伙伴们,如果还看不懂,在评论区留言,乐意解答。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值