算法与数据结构(4): 希尔排序


文章目录

  • 1 希尔排序
  • 2 实现简单的希尔排序
  • 参考资料

注:转载请标明原文出处链接:https://xiongyiming.blog.csdn.net/article/details/100558613


1 希尔排序

希尔排序 (Shell’s Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因D.L.Shell于1959年提出而得名。
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止
希尔排序按其设计者希尔(Donald Shell)的名字命名,该算法由希尔1959年公布。一些老版本教科书和参考手册把该算法命名为Shell-Metzner,即包含Marlene Metzner Norton的名字,但是根据Metzner本人的说法:“我没有为这种算法做任何事,我的名字不应该出现在算法的名字中。”

希尔排序是基于插入排序的以下两点性质而提出改进方法的:
(1) 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。
(2) 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位。
(以上均来自百度百科)

希尔排序的基本思想:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。

算法步骤:
选择一个增量序列 t 1 t_1 t1 t 2 t_2 t2,……, t k t_k tk,其中 t i t_i ti> t j t_j tj, t k t_k tk = 1;
按增量序列个数 k k k,对序列进行 k k k 趟排序;
每趟排序,根据对应的增量 t i t_i ti,将待排序列分割成若干长度为 m m m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

下面举个例子进行说明:

算法与数据结构(4): 希尔排序_第1张图片


动态示意图如下所示
算法与数据结构(4): 希尔排序_第2张图片

希尔排序算法复杂度为 O ( n 2 ) O( {n^2}) O(n2)



2 实现简单的希尔排序


代码示例 (C++)

#include

using namespace std;


template<typename T>
//使用希尔排序 让数组中的数字从小到大排序 //
void shellSort(T arr[], int n)
{
	//计算 increment sequence(增量序列) 1, 4. 13, 40,121,...
	int h = 1;
	while (h < n / 3) 
	{
			h = 3 * h + 1;
	}
		

	while (h >= 1) 
	{
		// 
		for (int i= h; i < n; i++) 
		{
			// 对arr[i], arr[i-h], arr[i-2h], arr[i-3h]... 使用插入排序
			T e = arr[i];
			int j;
			for (j = i; j >= h && e < arr[j - h]; j =j- h) 
			{
				arr[j] = arr[j - h];
			}

			arr[j] = e;
		}

		h = h / 3;
	}

}


int main() {

	int a[10] = { 10,9,8,7,6,5,4,3,2,1 };
	shellSort(a, 10);
	for (int i = 0; i < 10; i++)
		cout << a[i] << " ";
	cout << endl;

	cin.get();
	return 0;
}

运行结果

算法与数据结构(4): 希尔排序_第3张图片




参考资料

[1] 算法与数据结构–综合提升篇(c++版)
[2] https://www.jianshu.com/p/40dcc3b83ddc
[3] https://cuijiahua.com/blog/2017/12/algorithm_3.html
[4] https://www.cnblogs.com/chengxiao/p/6104371.html

你可能感兴趣的:(算法与数据结构专栏)