基本排序----希尔排序

本文介绍了希尔排序的基本思想及其算法实现过程。希尔排序通过逐步减少增量来提高直接插入排序的效率,适用于大规模数据集。文章详细展示了排序过程,并提供了C语言实现示例。

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

希尔排序基本思想

  基本思想 
希尔排序(Shell Sort)又称为“缩小增量排序”。是1959年由D.L.Shell提出来的。该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高。
具体做法:首先确定一组增量d0,d1,d2,d3,...,dt-1()其中n>d0>d1>...>dt-1=1),对于i=0,1,2,...,t-1,依次进行下面的各趟处理:根据当前增量di将n个元素分成di个组,每组中元素的下标相隔为di;再对各组中元素进行直接插入排序.
2、下面给出希尔排序算法的执行过程。

(1)采用希尔排序法排序的各趟的结果如下:
初始:503,17,512,908,170,897,275,653,426,154,509,612,677,765,703,94
第1趟{d1=8}:426,17,509,612,170,765,275,94,503,154,512,908,677,897,703,653
第2趟(d2=4):170,17,275,94,426,154,509,612,503,765,512,653,677,897,703,908
第3趟(d3=2):170,17,275,94,426,154,503,612,509,653,512,765,677,897,703,908
第4趟(d1=1):17,94,154,170,275,426,503,509,512,612,653,677,703,765,897,908
(2)例如,n=8,数组a的八个元素分别为:17,3,30,25,14,17,20,9。


C语言源代码:

#include <stdio.h>

void shSort(int a[], int n);

int main(void)
{
	int i;
	int a[] = {503,17,512,908,170,897,275,653,426,154,509,612,677,765,703,94};
	shSort(a, 16);

	for(i = 0; i < 16; i++)
	{
		printf("%-5d", a[i]);
	}

	return 0;
}

void shSort(int a[], int n)
{
	int d, i, j, x;
	d = n / 2;

	while(d >= 1)
	{
		/*
			从数组下标为d的元素开始与前一个数组元素比较
			直到数组的最后一个元素
		*/
		for (i = d; i < n; i++)
		{
			//获取数组中要比较的两个数值中的后一个数值
			x = a[i];					
			//获取数组中要比较的前一个数值的下标
			j = i - d;					
			/*
				首先要保证得到的下标大于等于0,也就是这个数值在数组中存在
				其次,后一个数值比前一个数值大,则交换彼此的值
			*/
			while(j >= 0 && a[j] > x)	
			{
				//将序列中前面大的数值赋给后面小的数值存放的空间
				a[j+d] = a[j];	
				/*
					这里为什么需要使用j-d
					因为j = i -d;
					当需要前后数值进行交换时,就必须将下标为j
					的数值存放到j+d里面去,下标j里面需存放下标为j+d(即临时变量x)的数值,
					当不需要交换数值时,下标j+d的数值就是其自身。
					j = j -d + d = j = i - d,保证了无论是否发生交换,
					a[j+d] = x都有通用性。
				*/
				j = j - d;				
			}
			/*
				保存数据
			*/
			a[j+d] = x;					
		}	
		d /= 2;							//缩小增量
	}
}

结果图片:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值