直接插入排序与希尔排序

直接插入排序与希尔排序_第1张图片

个人名片:

作者简介:一名乐于分享在学习道路上收获的大二在校生
‍❄个人主页:GOTXX

个人WeChat:ILXOXVJE
本文由GOTXX原创,首发CSDN

系列专栏:零基础学习C语言----- 数据结构的学习之路
每日一句:如果没有特别幸运,那就请特别努力!
————————————————

文章简介:

本篇文章对 直接插入排序与希尔排序 的相关知识详细讲解!

如果您觉得文章不错,期待你的一键三连哦,你的鼓励是我创作动力的源泉,让我们一起加油,一起奔跑,让我们顶峰相见!!!


目录

1.直接插入排序

1.1基本思想:

代码实现:

1.2性能分析

1.2.1时间复杂度:

1.2.2空间复杂度:没有空间消耗

2.希尔排序

2.1基本思想:

代码实现:

2.2性能分析

2.2.1时间复杂度

2.2.2空间复杂度


1.直接插入排序

1.1基本思想:

1.假设一个数组中前n-1个数都有序了,将最后一个数插入到前面有序的数组中去,用待插入数与有序数组从后向前依次比较,直到找到比待插入数大(降序)或则小(升序)的数,将该数插到其后面; 

2.一个无序的数组中,将第一个数看成有序的,将第二个数插入到前面,把前面两个变成有序;

3.再将第三个数插入到前面有序数组中,将前三个变成有序;

.......

将最后一个元素插入到前面的数组中去,整个数组就有序了;

图解:

直接插入排序与希尔排序_第2张图片

直接插入排序与希尔排序_第3张图片

代码实现:
//升序为例
void InsertSort(int a[],int n)
{
	for (int i = 1; i < n - 1; i++)
	{
		int end = i;
		//将最后一个元素保存,避免当倒数第二个数比它大,往后移动时将它覆盖
		int tmp = a[end];
		while (end >= 0)
		{
			//从后向前比较,当比他大时,将该元素往后移动
			if (a[end - 1] > tmp)
			{
				a[end] = a[end - 1];
			}
			end--;
			//当找到比它小的数时,break跳出循环
			if (a[end - 1] <= tmp)
			{
				break;
			}
		}
		//到这里有两种情况,1  end<0 退出循环  2  找到了比它小的数,break跳出循环
		a[end] = tmp;
	}

}

1.2性能分析

1.2.1时间复杂度:


最坏情况,逆序

时间复杂度为:1+2+3+4+……+n-1+n

时间复杂度为:O(N^2)

1.2.2空间复杂度:没有空间消耗

空间复杂度:O(1)

2.希尔排序

2.1基本思想:

先选定一个整数(记作gap)作为间距,把待排序的数据以gap间距分组,并对每一组的数据进行插入排序,然后再缩小间距(gap),当gap最后等于1时,所有数据就有序了;

希尔排序要先进行预排序,预排序完后再进行一次直接插入

当gap>1时,就是预排序;

当gap=1时,就相当于直接插入排序;

预排序:

预排序是在选择排序的思想上,将一组数据以gap为数据间隔分组;如图

直接插入排序与希尔排序_第4张图片

再将每一组数据进行直接选择排序;(如下图)

预排序的意义:是让大的数更快到后面去,小的数更快到前面去;如图:

预排序过后,在进行gap为1的直接插入排序之前,数组的数据已经很接近有序了,所以最后一次的直接插入排序在时间上有了优化;

直接插入排序与希尔排序_第5张图片

代码实现:
void ShellSort(int* a, int n)
{
	int gap = n;
	while (gap>1)
    {
		//当gap>1时,预排序,gap=1时,直接让数组有序;
		gap = gap / 3 +1;

		//一共分为了gap组,需要gap次的插入排序
		for (int j = 0; j < gap; j++)
		{    
            //一组数据的插入排序
			for (int i = j; i < n - gap; i += 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;
			}
		}
	}
}

2.2性能分析

开始时,gap取值较大,子序列中的元素较少,排序速度快,克服了直接插入排序的缺点;

其次,gap值逐渐变小后,虽然子序列的元素逐渐变多,但大多元素已基本有序,能以近线性的速

度排好序;

2.2.1时间复杂度

根据复杂的数学计算,结论为:

时间复杂度为O(N^1.3)

2.2.2空间复杂度

除了两个数据交换时有空间消耗,就没有多余其他空间的消耗;

最好:有序       空间复杂度为0;

最坏:逆序       空间复杂度为O(N);

平均空间复杂度为O(1)


你可能感兴趣的:(数据结构的学习之路,排序算法,算法,数据结构)