希尔排序-排序算法

前言

希尔排序固然很好,但是某些情况下,有很多缺点。例如下面这种情况:

9 之前的元素都已经有序,只有元素 1 和 2 的位置不对,使用插入排序几乎要移动整个数组的元素,效率很低。

这时候希尔排序横空出世,为的就是应对这种情况,希尔排序(ShellSort)是希尔提出的一种排序算法,它也是插入排序的一种,是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,也就是它会优先比较距离较远的元素。

希尔排序是把记录按一定的增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的元素越来越多,当增量减至1时,所有元素被分成一组,实际上等同于执行一次上面讲过的插入排序,算法便终止。

从上面这一段话中,你可能不知道什么是增量,增量怎么选取,如何分组。接下来看看具体步骤。(学习希尔排序前最好是已经知道插入排序)

步骤

这是原始的数组,颜色相同的为一组。

初始增量 gap = length / 2 = 5 ,所以我们要分为 5 组,分别是:【8,3】【9,5】【1,4】【7,6】【2,0】

对这 5 组分别进行直接插入排序,如下图,可以看到,较小的元素移动到了前面。然后缩小增量 gap = gap / 2 = 2,那么要分为两组.

对上面两组再分别进行直接插入排序,下图可以看到,此时整个数组的有序程度更近一步啦,再缩小增量 gap = gap / 2 = 1 ,整个数组被分为一组。

经过上面的"调整",此时再也不像刚开始时:需要大量移动元素。对上面一组进行一趟插入排序,就可得到有序序列,增量再次减小 gap = gap / 2 = 0,此时停止。

这就是整个过程,其中需要对插入排序的过程十分了解才行,接下来直接撸代码。

代码

复制代码
#include <iostream>
using namespace std;

void ShellSort(int arr[], int left, int right)
{
	int gap = (right - left + 1) / 2; //初始增量设为长度的一半


	for (; gap > 0; gap = gap /2) 
	{
		for (int i = gap; i <= right; i++) //对每一个数在其分组进行插入排序
		{
			int current = arr[i];
			int j = i - gap; 
			while (j >= 0 && arr[j] > current)
			{
				arr[j + gap] = arr[j];
				j -= gap;
			}
			arr[j + gap] = current;

		}
	}

}

int main(void)
{

	int arr[] = { 3,4,5,6,7,8,9,10,1,2 };
	int len = sizeof(arr) / sizeof(arr[0]);

	ShellSort(arr, 0, len - 1);

	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << " ";
	}

	return 0;
}

如果上面的代码看不懂,可以结合过程推导

相关推荐
Asize4 小时前
146. LRU 缓存
算法
Asize4 小时前
543. 二叉树的直径
算法
lemon_sjdk4 小时前
ObjectProperty
java·开发语言·算法
Zentceh5 小时前
AI-ISP在夜视机芯中的应用:从传统ISP到PixelClean全彩夜视的进化
人工智能·科技·算法·计算机视觉·车载系统·视频·智能硬件
xier_ran5 小时前
【infra之路】AWQ 详解:激活感知权重保护,让 W4A16 量化精度超越 GPTQ
线性代数·算法·机器学习·量化·infra
亦皓ai6 小时前
AI时代后端工程(二):AI把代码写得越来越快,我却越来越不敢让它直接开工了
人工智能·算法·机器学习·搜索引擎·transformer
玖玥拾7 小时前
LeetCode 392 判断子序列
笔记·算法·leetcode
不灭的黄金瞳1237 小时前
C语言手写顺序表
c语言·开发语言·数据结构
qeen878 小时前
【数据结构】哈希表的C++实现与封装
数据结构·c++·散列表·哈希表
重生之后端学习8 小时前
239. 滑动窗口最大值[困难]✅
java·数据结构·算法·leetcode·职场和发展