希尔排序(C语言)

希尔排序

一、什么是希尔排序;

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

二、希尔排序的思想;

希尔排序是插入排序的提升(如果没了解过插入排序建议先去看看插入排序)。他是通过将数据根据每一次的步长不断地分块,并且进行处理,使得数值序列整体上变得不会太过杂乱。使得在利用插入排序的过程中减少交换的次数,从而进行优化。

三、步长(增量)

希尔当年提出n/(2^k),k取1,2,3,4……(n代表数据个数),从而计算出步长。
例如:{9, 5, 2, 7, 8, 1, 3, 5, 4, 8, 7, 6, 2, 1, 5}
根据希尔的公式可以计算出:
(以下除法运算接按照C语言整数除法运算法则)
第一次所需步长是:15 / 2 = 7;
第二次所需步长是:7 / 2 = 3;
第三次所需步长是:3 / 2 = 1;
当步长为一时,所进行的排序和插入排序完全相同,只不过此时的数据在经过前面几次的排序后数值序列已经被进行优化。所以会加快数据的排序。

四、复杂度分析
  • 时间复杂度O(n^(1.3~2));
  • 空间复杂度O(1);
  • 稳定性·:非稳定;
五、图解过程

在这里插入图片描述
第一次步长为4,所以将每个数据与之相隔第四个数据进行比较;结果如第二行所示。第二次步长为二,所以在第一排好的序列下再以以二为步长进行排序。直到步长为一时完成排序。

六、代码实现
#include <stdio.h>

#define N 9

//打印
void prin_arr(int *arr);
//排序过程
void shell_sort(int *arr, int n);

void shell_sort(int *arr, int n) {
	int step;		//步长;
	int key;		//保护每一组数据排序时的第二个数据;
	int i;			
	int j;
	//该排序过程是多组数据同时进行,并不是一组一组的进行;
	for (step = N / 2; step > 0; step /= 2) {
		for (i = step; i < N; i++) {	
			key = arr[i];	//保护数据
			for (j = i - step; j >= 0 && arr[j] > key; j -= step) {
				arr[j + step] = arr[j];
			}
			arr[j + step] = key;		//将保护的数据放到合适的位置;
		}
	}
}

void print_arr(int *arr) {
	int i;

	for (i = 0; i < N; i++) {
		printf("%d ", arr[i]);
	}
	printf("\n");
}
int main() {
	int arr[] = {9, 5, 2, 7, 6, 5, 4, 9, 8};
	
	print_arr(arr);
	shell_sort(arr, N);
	print_arr(arr);

	return 0;
}
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值