排序 -- 插入排序和希尔排序

排序 – 插入排序和希尔排序


一、插入排序

1.排序思想

直接插入排序的基本思想是:把待排序的数据按其关键码值的大小,依次插入一个已经排好序的序列中,直到所有的数据都插入完成,得到一个新的有序序列。
请添加图片描述
如上图所示,再插入第i个数据时,前面的a[0]~a[i-1]个数据已经排好序,只需将a[i] 和前面的i个数据依次比较,比a[i]大的数据直接向后挪,空出当前位置,直到找到比a[i]小的数据或者数组到头后,将a[i]填入空位中,就完成了一次单躺排序。

2.代码示例

代码如下:

void InsertSort(int* a, int sz)
{
	for (int i = 0; i < sz - 1; i++)//边界条件是end走到倒数第二个数据,tmp是最后一个
	{
		//单躺排序:[0, end]有序,把end + 1位置上的数插入,保持有序
		int end = i;
		int tmp = a[end + 1];//使用tmp保存当前数据,前面的数据就可以直接覆盖

		while (end >= 0)
		{
			if (tmp < a[end])
			{
				a[end + 1] = a[end];//直接覆盖
				--end;
			}
			else
			{
				break;
			}
		}
		a[end + 1] = tmp;
	}
}

3.特性总结

1.原序列越接近有序,直接插入排序的效率越高;
2.时间复杂度:最好:顺序O(N),最坏:完全逆序O(N^2)
3.空间复杂度:O(1);
4.稳定性:稳定(不会改变相同码值数据的相对顺序)。

二、希尔排序

1.排序思想

希尔排序法又称缩小增量法,其基本思想是:将整个数据以间隔为gap分割成各组数据,然后将各组数据进行插入排序。然后不断减小gap,直到gap = 1时,就成为直接插入排序。
gap > 1时是预排序,gap = 1时是直接插入排序,这样操作的原因是:越有序的数据,插入排序越快
间距为gap的是一组数据
如上图所示,第一趟排序时gap为5,间隔为5的数据为一组,整个序列共分为5组,每组数据都进行插入排序,使各组数据都有序;第二趟gap为2,间隔为2的数据为一组,共2组,再次进行插入排序,直到最后gap为1,进行的就是直接插入排序。
gap由大到小,整个序列不断接近有序,到最后gap = 1时,直接插入排序的效率会很高。

2.代码示例

预排序:

//整个预排序
	int gap = 3;//间距为gap是一组数据
	for (int i = 0; i < gap; i++)//每次预排序一共排gap组数据
	{
		//单躺预排序,相当于插入排序
		for (int j = i; j < sz - gap; j += gap)//边界条件是:end为倒数第二个数据,所以 j < sz - gap
		{
			int end = j;
			int tmp = a[end + gap];

			while (end >= 0)
			{
				if (tmp < a[end])
				{
					a[end + gap] = a[end];
					end -= gap;
				}
				else
				{
					break;
				}
			}
			a[end] = tmp;
		}
	}

希尔排序:

void ShellSort(int* a, int sz)
{
	//gap > 1时是预排序,gap = 1时是直接插入排序
	int gap = sz;
	while (gap > 1)
	{
		gap = gap / 3 + 1;//gap由大到小,最后等于1时就是插入排序
		//加一的原因是:保证最后一个gap一定是1当上一个gap < 3是,下一个gap就是0了

		//整个预排序:i一个一个走,但是每次tmp都是end + gap的数据,还是相当于对间隔为gap的数据进行插入排序
		for (int i = 0; i < sz - gap; i++)//边界条件是:end为倒数第二个数据,所以 i < sz - gap
		{
			int end = i;
			int tmp = a[end + gap];

			while (end >= 0)
			{
				if (tmp < a[end])
				{
					a[end + gap] = a[end];
					end -= gap;
				}
				else
				{
					break;
				}
			}
			a[end + gap] = tmp;
		}
	}
}

3.特性总结

1.希尔排序是对直接插入排序的优化;
2.时间复杂度:计算比较复杂,大致为O(N^1.3);
3.空间复杂度:O(1);
4.稳定性:不稳定,可能会打乱相同码值数据之间的相对顺序。


总结

以上就是本次要讲的内容,本文简单介绍了直接插入排序和希尔排序的思想、代码与特性,不足之处还望各位大佬指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值