希尔排序,详细解析(附图解)

1.希尔排序思路

希尔排序是一种基于插入排序的算法,通过将原始数据分成若干个子序列,然后对子序列进行插入排序,逐渐减小子序列的间隔,最后对整个序列进行一次插入排序。

1.分组直接插入排序,目标接近有序-----------gap>1

2.直接插入排序,目标有序-----------------------gap=1

2.分组排序思路分析

假设固定gap=3,那么以下数组可以分为三组

每一组都使用用直接插入排序,使数据有序

最后三组都排完后数组变成了:0,2,1,4,3,6,5,7,8,此时的结果接近有序

此时只需要再调用一次插入排序,即可让整个数组变得有序。

下面我们来实现一下这个

2.1思路代码

cpp 复制代码
void ShellSort(int* a, int n)
{
	int gap = 3;
	for (int j = 0; j < gap; j++)
	{
		for (int i = j; i < n - gap; i += gap)
		{
			int end = i;
			int tmp = a[end + gap];
			while (end >= 0)
			{
				if (a[end] > tmp)
				{
					a[end + gap] = a[end];
					end -= gap;
				}
				else
				{
					break;
				}
			}
			a[end + gap] = tmp;
		}
		for (int i = 0; i < n; i++)
		{
			printf("%d ", a[i]);
		}
		printf("\n");
	}
}

在每一组排序后都打印一下来观察

2.2结果显示

3.gap的设定

当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。

当我们不再固定gap而是让他变化时,如下图gap=gap/2;

3.1动图演示

一般现在认为gap=gap/3+1较为合适,我们以此来实现一下代码

3.2最终代码实现

这里省去了一层for循环,把原本一组一组交换变为了组之间交替交换,时间复杂度没有改变。

cpp 复制代码
//升序
void ShellSort(int* a, int n)
{
	int gap = n;
	while (gap > 1)
	{
		gap = gap / 3 + 1;
		for (int i = 0; i < n - gap; i++)
		{
			int end = i;
			int tmp = a[end + gap];
			while (end >= 0)
			{
				if (a[end] > a[end + gap])
				{
					a[end + gap] = a[end];
					end -= gap;
				}
				else
				{
					break;
				}
			}
			a[end + gap] = tmp;
		}
	}
}

4.时间复杂度

记忆:O(N^1.3)

比O(N*logN)大,比O(N^2)小

希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的希尔排序的时间复杂度都不固定

相关推荐
TimberWill5 分钟前
哈希-03-字母异位词分组
算法·哈希算法
轻微的风格艾丝凡8 分钟前
matlab推导QPR离散公式并验证
算法·matlab·谐振
全栈陈序员10 分钟前
v-if 和 v-for 的优先级是什么?
前端·javascript·vue.js·学习·前端框架·ecmascript
全栈陈序员16 分钟前
你对 SPA 单页面应用的理解?它的优缺点分别是什么?如何实现 SPA 应用?
前端·vue.js·学习·前端框架·vue
Cowboy hat21 分钟前
数据结构基础(一)—— 什么是数据结构?
数据结构
soumns丶涛23 分钟前
ESP32学习(1) - 点亮第一个LED
学习
superman超哥28 分钟前
仓颉性能瓶颈定位方法深度解析
c语言·开发语言·c++·python·仓颉
全栈陈序员33 分钟前
请描述下你对 Vue 生命周期的理解?在 `created` 和 `mounted` 中请求数据有什么区别?
前端·javascript·vue.js·学习·前端框架
岁岁的O泡奶34 分钟前
NSSCTF_crypto_[SWPU 2020]happy
经验分享·python·算法·密码学
代码游侠35 分钟前
应用——UDP Socket 编程笔记
linux·运维·网络·笔记·网络协议·学习·udp