希尔排序-排序算法

前言

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

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

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

相关推荐
chao1898443 小时前
基于 SPEA2 的多目标优化算法 MATLAB 实现
开发语言·算法·matlab
沪漂阿龙3 小时前
AI大模型面试题:支持向量机是什么?间隔最大化、软间隔、核函数、LinearSVC 全面拆解
人工智能·算法·支持向量机
難釋懷3 小时前
Redis数据结构-Set结构
数据结构·redis·bootstrap
little~钰3 小时前
倍增算法和ST表
算法
知识领航员4 小时前
蘑兔AI音乐深度实测:功能拆解、实测表现与适用场景
java·c语言·c++·人工智能·python·算法·github
薛定e的猫咪4 小时前
因果推理研究方向综述笔记
人工智能·笔记·深度学习·算法
如何原谅奋力过但无声5 小时前
【灵神高频面试题合集06-08】反转链表、快慢指针(环形链表/重排链表)、前后指针(删除链表/链表去重)
数据结构·python·算法·leetcode·链表
平行侠5 小时前
037插入排序 - 整理扑克牌的算法
数据结构·算法
ECT-OS-JiuHuaShan6 小时前
彻底定理化:从量子纠缠到量子代谢
数据库·人工智能·学习·算法·生活·量子计算