排序之希尔排序

本文介绍了希尔排序的基本原理,即通过分组和预排序逐步缩小间隔实现高效排序,同时讨论了不同gap的选择及其对排序性能的影响,最后提出了优化策略以适应不同规模的数组。
摘要由CSDN通过智能技术生成

希尔排序作为很有效率的排序之一,值得我们如了解他的原理和形式,所以今天我们浅谈的是希尔排序

希尔排序的原理

希尔排序指的是:一组数按gap进行分组,每个间隔为gap的数为一组,这样形式的分组可以有gap组。
在这里插入图片描述
如图,如果我按gap=3来分组的话,一共可以分成三组,每组中的每个组间隔都为gap。
那么我们要是希尔排序的特性
1.希尔排序是对直接插入排序的优化;
2.当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,相当于直接插入排序。
所以从特性上来说希尔排序的内核还是和直接插入排序有一定的关系。让我们看看它的原理图:
因为我们分好的组,所以当我们按一组一组的排序,最后就会达到相对有序的情况,例如绿色组在这里插入图片描述

//部分代码展示:只排列绿色组
int end=0;
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;

在这里插入图片描述
会发现和我们预先的思路图的位置一样。那么如果我一组一组的排列且我要排列gap=3组时,的代码为:

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)
		{
		//为什么是i < n - gap,如果是n的话,当end+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;
		}
	}
}

那么如果我多组混合排序呢?**是不是相当于排完绿色组,i++后排红色组,然后i++排蓝色组,然后又到绿色…直到不满足限定条件为止。**如图:
在这里插入图片描述

void ShellSort(int* a, int n)
{
	int gap = 3;
	for(int j=0;j<gap;j++)
	{ 
		for (int i = 0; i < n - gap; i++)
		{
			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;
		}
	}
}

希尔排序的优化

上述我们确实可以对数组进行快速排序,但是如果我的数组很大很大那么gap=3他还合理吗?如果我的数组很小,那么gap=3合理吗?所以我们需要对希尔排序进行gap的优化。根据希尔排序的特性,当gap==1时,相当于直接插入排序,也就是将无序变为有序的最终步骤,那么我们让gap最终等于1即可,当gap>1时,都是预排序。

void ShellSort(int* a, int n)
{
	int gap = n;
	while (gap > 1)
	{
		gap = gap / 3 + 1;
		//这里gap只要保证等于1就可以,应为当gap==1的时候,相当于直接插入排序
		//将前面的预排序最后整理。
		for (int i = 0; i < n - gap; i++)
		{
			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;
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值