排序算法:希尔排序

具体思路:

1.设置增量,依据增量把数组分成若干组
2.每次遍历将每个组依次进行插入排序
3.改变增量大小(重复执行2,3步骤) 

示例代码:

#include <stdio.h>
#include <math.h>

void shellSort(int a[], int n) {
	int gap = n;
	while (gap != 0) { 
		gap = floor(gap/2);//增量为gap,gap不断缩小为本身的二分之一 ,用floor()函数,保证gap最后都能取到1,确保算法正确性 
		for (int i = 0; i < gap; i++) { //可知增量的大小即为组数,将数组分成了gap组 
			for (int j = i+gap; j < n; j += gap) { //对每一组进行插入排序 
				if (a[j] < a[j-gap]) {
					int k = j-gap;
					int tmp = a[j];
					while (a[k] > tmp && k >= 0) {
						a[k+gap] = a[k];
						k -= gap;
					}
					a[k+gap] = tmp; 
				}
			}
		}
	}
}

int main() {
	int a[10],n = 10;
	for (int i = 0; i < n; i++) 
		scanf("%d", &a[i]);
	shellSort(a, n);
	for (int j = 0; j < n; j++) 
		printf("%d ", a[j]);
	printf("\n");
	return 0;
} 

算法分析:

第一次比较次数,每组2个元素:1*n/2

第二次比较次数,每组4个元素:最坏(1+2+3)*n/4

第三次比较次数,每组8个元素:最坏(1+2+3+……+7)*n/8

时间复杂度最坏情况为:O(n^2)

 

以下图示为转载内容

第1趟:(gap=4)

当gap=4时,意味着将数列分为4个组: {80,20},{30,10},{60,50},{40,70}。 对应数列: {80,30,60,40,20,10,50,70}
对这4个组分别进行排序,排序结果: {20,80},{10,30},{50,60},{40,70}。 对应数列: {20,10,50,40,80,30,60,70}


第2趟:(gap=2)

当gap=2时,意味着将数列分为2个组:{20,50,80,60}, {10,40,30,70}。 对应数列: {20,10,50,40,80,30,60,70}
注意:{20,50,80,60}实际上有两个有序的数列{20,80}和{50,60}组成。
          {10,40,30,70}实际上有两个有序的数列{10,30}和{40,70}组成
对这2个组分别进行排序,排序结果:{20,50,60,80}, {10,30,40,70}。 对应数列: {20,10,50,30,60,40,80,70}

 

第3趟:(gap=1)

当gap=1时,意味着将数列分为1个组:{20,10,50,30,60,40,80,70}
注意:{20,10,50,30,60,40,80,70}实际上有两个有序的数列{20,50,60,80}和{10,30,40,70}组成。
对这1个组分别进行排序,排序结果:{10,20,30,40,50,60,70,80}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值