希尔排序-排序算法

前言

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

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;
}

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

相关推荐
运筹vivo@2 分钟前
LeetCode 2405. 子字符串的最优划分
c++·算法·leetcode·职场和发展·哈希表
数智工坊3 分钟前
视觉-语言-动作模型解剖学:从模块、里程碑到核心挑战
论文阅读·人工智能·深度学习·算法·transformer
yuannl1013 分钟前
数据结构----二叉排序树(ai修改版)
数据结构
有点。29 分钟前
C++(枚举法一练习题)
开发语言·c++·算法
黎阳之光42 分钟前
视听融合新范式!黎阳之光打破视觉边界,声影协同赋能全域智慧管控
大数据·人工智能·物联网·算法·数字孪生
iiiiyu1 小时前
集合进阶(Map集合)
java·大数据·开发语言·数据结构·编程语言
sheeta19981 小时前
LeetCode 每日一题笔记 日期:2026.05.19 题目:2540. 最小公共值
笔记·leetcode·排序算法
小江的记录本1 小时前
【Java基础】核心关键字:final、static、volatile、synchronized、transient(附《思维导图》+《面试高频考点清单》)
java·前端·数据结构·后端·ai·面试·ai编程
玖釉-1 小时前
栈——栈的定义及基本操作
c++·windows·算法·图形渲染
ゆづき2 小时前
Java 初学者入门指南:常见问题 + 核心知识点 + 进阶 20 道练习题
java·开发语言·学习·算法·水题