【排序】希尔排序(C语言实现)

文章目录

  • 前言
  • 1. 希尔排序的思想
  • 2. 希尔排序的一些小优化



前言


本章将详细介绍希尔排序的思想及实现,由于希尔排序是在插入排序的思想上进行升华,所以如果不知道插入排序或者不熟悉的可以先看看这篇文章:《简单排序》中的直接插入排序。


1. 希尔排序的思想

希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成gap个组,所有距离为gap的数据分在同一组内,并对每一组内的记录进行排序。当gap组都排完以后,我们将gap缩小,重复上述分组和排序的工作。当gap = 1时(此时就是直接插入排序),所有记录在统一组内排好序。

【排序】希尔排序(C语言实现)_第1张图片

具体步骤如下图:

【排序】希尔排序(C语言实现)_第2张图片
【排序】希尔排序(C语言实现)_第3张图片
【排序】希尔排序(C语言实现)_第4张图片

我们可以按照上面的思路,来用代码进行模拟实现:

void ShellSort(int* a, int n)
{
	int gap = n;
	while (gap > 0)
	{
		// 每次gap/2,直到最后gap会等于0
		gap /= 2;
		int count = 0;
		// 调整几组取决于gap为多大
		while (count < gap)
		{
			// 每组调整的步骤
			for (int i = 0;i < n - gap;i += gap)
			{
				int tmp = a[i + gap]; // 定义一个临时值,用来保存每次要插入的数
				int j = 0; //控制循环的变量
				for (j = i;j >= 0;j -= gap)
				{
					// 从后面开始比,如果tmp比后面的数小,就将后面的数往后移gap
					if (a[j] > tmp)
						a[j + gap] = a[j];
					else// 如果tmp比后面的数要大,就直接退出,因为我们是从第一个数开始这样操作的,前面能够保证是有序的
						break;
				}
				a[j + gap] = tmp;
			}

			count++;
		}
	}
}

希尔排序的特性总结:

  1. 希尔排序是对直接插入排序的优化。
  2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。
  3. 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的希尔排序的时间复杂度都不固定:
    《数据结构(C语言版)》— 严蔚敏【排序】希尔排序(C语言实现)_第5张图片
    《数据结构-用面相对象方法与C++描述》— 殷人昆
    【排序】希尔排序(C语言实现)_第6张图片
  4. 稳定性:不稳定


2. 希尔排序的一些小优化

我们上面那个实现的方式是取gap=[n / 2],gap=[gap / 2],直到gap=1,但我们看到 《数据结构-用面相对象方法与C++描述》— 殷人昆 中提到Hnuth取gap的方法,可以有一定程度上的提高我们的速度,具体是怎么提高的呢,因为这块涉及到很难的数学知识,目前还没人能够给出完整的数学分析,所以我们也不必去纠结,只要记住他们这些大佬经过多次实验提出的结论就可以了。

这里我打算进行两个优化:

  1. 就是gap的取值
  2. 我们上面每次排序是一组一组的排序,其实我们可以一次性全部排序完(这里效率上没有提升,只是代码量减少了)

具体代码如下:

void ShellSort(int* a, int n)
{
	int gap = n;
	while (gap > 1) // gap最小等于1,所以这里的循环条件需要控制一下
	{
		// 每次gap/3 + 1,+1的目的是为了保证gap一定会等于1
		gap = gap / 3 + 1;
		// 我们将gap组一起调整
		for (int i = 0;i < n - gap;++i)
		{
			int tmp = a[i + gap];// 定义一个临时值,用来保存每次要插入的数
			int j = 0; // 控制循环的变量
			for (j = i;j >= 0;j -= gap)
			{
				if (a[j] > tmp)
				{
					a[j + gap] = a[j];
				}
				else
					break;
			}
			a[j + gap] = tmp;
		}
	}
}

你可能感兴趣的:(排序,c语言,排序算法,算法)