插入排序与希尔排序

个人主页:Lei宝啊

愿所有美好如期而遇


前言:

这两个排序在思路上有些相似,所以有人觉得插入排序和希尔排序差别不大,事实上,他们之间的差别不小,插入排序只是希尔排序的最后一步。


目录

前言:

插入排序:

思路:

图解:

代码:

希尔排序:

思路:

图解:

代码:


插入排序:

思路:

当我们有了一个有序的数组arr,假设为升序,现在向里面插入一个新数据。

我们假设这个数组有n个元素,最后一个元素的下标我们记作end,那么要插入的这个数下标为end+1,并用tmp记下这个数的大小。

接下来,如果tmp小于arr[end],那么arr[end+1] = arr[end];  end--,

              如果tmp大于等于arr[end],那么break;   arr[end+1] = tmp;  

重复上述操作,直到end < 0或者break跳出


那么面对一个无序的数组,我们可以将第一个元素当做有序,第二个元素为新插入元素,依次类推排序

图解:

代码:

void InsertSort(int* arr, int n)
{
	
	//i == n - 2时,temp = arr[n - 1];
	for (int i = 0; i < n - 1; i++)
	{
		int end = i;
		int temp = arr[end + 1];

		//此处画个图,end小于0跳出循环
		while (end >= 0)
		{
			if (temp < arr[end])
			{
				//插入的值比end小,end值向后移动一位
				arr[end + 1] = arr[end];
				end--;
			}
			else
			{
				break;
			}

		}
		//写在循环外的原因是如果while循环不是break出来的
		//会导致第一个元素值重复,插入的值最后未插入进去
		arr[end + 1] = temp;
	}
	
}

希尔排序:

思路:

希尔排序比插入排序多的就是预排序,而预排序的目的就是让大的数据/小的数据更快的被排到后面去,因为越接近有序的数据,使用插入排序时时间复杂度越接近O(N),而我们的希尔排序最后一步等同于插入排序

图解:

以代码一为例:

代码:

两个代码没有什么差别,只是一个是一组一组排,一个是并排。

代码一:
void ShellSort(int* arr, int n)
{

	int gap = n;

	while (gap > 1)
	{

		//多组预排序,最后接近有序时插入排序
		gap /= 2;

		//完成一趟预排序
		for (int j = 0; j < gap; j++)
		{
			//完成一组预排序
			for (int i = j; i < n - gap; i += gap)
			{
				//走一组中的一个位置的预排序
				int end = i;
				int temp = arr[end + gap];

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

				arr[end + gap] = temp;
			}

		}
	}
	
}
代码二:
void ShellSort(int* arr, int n)
{
	int gap = n;

	while (gap > 1)
	{

		//多组预排序,最后接近有序时插入排序
		gap /= 2;
		
		//等同于上面的希尔排序,不是分组排了,而是并排
		for (int i = 0; i < n - gap; i++)
		{
			//走一组中的一个位置的预排序
			int end = i;
			int temp = arr[end + gap];

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

			arr[end + gap] = temp;
		}	
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lei宝啊

觉得博主写的有用就鼓励一下吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值