排序算法(希尔排序)

希尔排序是插入排序的改进版,通过设置间隔h进行元素交换,提高排序效率。它首先选择一个较大的间隔进行局部排序,然后逐渐减小间隔,直到间隔为1,此时演变为插入排序。希尔排序的性能依赖于h的选择序列,虽然具体比较次数不确定,但在处理大规模乱序数组时表现优秀。

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

2018-11-5:简单排序算法:希尔排序

算法3:希尔排序

基本思想

  1. 希尔排序是基于插入排序的一种快速排序算法
  2. 对于大规模乱序数组来说,插入排序很慢。因为它只会交换相邻的元素,因此元素只能一点点地从数组的一端移动到另一端。比如说,如果最小的元素恰好在数组的末尾,要将它挪到正确的位置,插入排序要进行N-1次挪动。
  3. 希尔排序是为了加快插入排序,每次不再只和相邻的元素交换,而是每次交换不相邻(间隔为h)的元素来对数组进行局部排序,h逐渐递减为1,当h=1时,希尔排序实际上退化为插入排序,也就是说最终是使用插入排序将局部有序的数组排好序。

特点

  1. 希尔排序的思想是使任意间隔为h的元素有序。这样的数组称为h有序数组。举个例子,假如有下面这样的乱序数组,h取5。
    在这里插入图片描述
    则希尔排序第一次迭代会使得
    第1位元素:8和第6(1+5)位元素:9,有序
    第2位元素:1和第7(2+5)位元素:10,有序
    第3位元素:5和第8(3+5)位元素:2,有序,变成2,5
    第4位元素:6和第9(4+5)位元素:3,有序,变成3,6
    第5位元素:7和第10(5+5)位元素:4,有序,变成4,7
    希尔排序第一次迭代后的数组如下,有颜色的数字是发生了交换:
    在这里插入图片描述
    所以我们可以看到,如果h很大,我们就可以把元素一步移到很远的地方去,为实现更小的h有序创造方便,比如说将第8位元素直接经过一步交换直接移到了第3位。如果按照插入排序老老实实地进行相邻交换,可能的需要交换5次。
  2. 希尔排序中的h并不是固定不变的,h先取一个较大的值,然后逐渐递减(这个递减并不一定是每次减少1,有可能减少2),直到h变成1。当h=1时,希尔排序也就退化成插入排序了。
  3. 如何选取h的取值序列呢?这是一个复杂的数学问题。另外,希尔排序的算法性能不仅取决于h,还取决于h之间的数学性质。

代码实现

//希尔排序
void swap(int *a,int i,int j)
{
	int t=a[i];
	a[i]=a[j];
	a[j]=t;
}
void shellsort(int a[], int n)
{
	int h=1;
	while(h<n/3) //计算h的序列
		h=3*h+1;
	while(h>=1)
	{
		for(int i=h;i<n;i++)
		{
			//将a[i]插入到a[i-h],a[i-2*h],a[i-3*h]...中
			for(int j=i;j>=h&&a[j]<a[j-h];j-=h)
				swap(a,j,j-h);
		}
		h=h/3;
	}
}


亮点

  1. 希尔排序实际上是一个类似于插入排序但是用了不同增量h的过程
  2. 输入一个随机的排序数组,在数学上居然还是不知道希尔排序所需要的平均比较次数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值