C语言---插入排序(直接插入和希尔)


前言

插入排序一般分为两种,一种直接插入排序,另一种则是希尔排序

一、直接插入排序

1.简介

  直接插入排序是一种简单的排序方法,基本操作就是将需要排序的元素插入到已排好的有序表序列中,从而得到一个完整的序列。
  时间复杂度为:O(n²)    空间复杂度:O(1)      稳定性:稳定
  生活中最明显的例子就是,打扑克,把牌洗混,然后抓牌,以第一张为基础,然后将后面的牌依次插入,最后得到有顺序的牌面。

2.算法思路

  1. 待排的序列看作成2个部分,一部分为有序,另一部分为无序。
  2. 我们将第一个元素看作有序序列,第二个到最后都是无序序列。
  3. 将无序序列的每一个元素依次插入到有序序列的合适位置。在这里插入图片描述
    讲解:有一个待排序序列:【2,5,8,3】
    我们将第一个2看成已经排序好的序列,即有序序列,从第二个元素最后一个元素看作是无序序列。
    排序元素有序元素大,则插在有序元素后,反之,插在有序元素

3.代码实现

#include<stdio.h>
#define num 12
void insert_sort(int* a, int n)
{
	
	for (int i = 0; i < n - 1; ++i)
	{
		// 将x插入[0, end]有序区间
		int end = i;
		int x = a[end + 1];
		while (end >= 0)
		{
			if (a[end] > x)
			{
				a[end + 1] = a[end];
				end--;
			}
			else break;
		}
		a[end + 1] = x;
	}
}
int main()
{
	int arr[num] = { 3,1,4,5,2,7,9,0,8,10,11,6 };
	printf("\n初始序列\n");
	for (int i = 0; i < num; i++)
	{
		printf("%d ", arr[i]);
	}
	insert_sort(arr, num);
	printf("\n排序后序列\n");
	for (int i = 0; i < num; i++)
	{
		printf("%d ", arr[i]);
	}
}

运行结果:
在这里插入图片描述

二、希尔排序

1.简介

希尔排序是在直接插入排序的基础上做了较大的改进,是将整个无序序列分割成若干个的子序列分别进行插入排序。
简单而言:将数组预排序,接近有序。
元素为逆排序时,时间复杂度最差为O(n²) 空间最差复杂度: O(n)
平均时间复杂度为O(nlog2n) 平均空间复杂度(O(1))
稳定性:差

2.算法思路

  1. 先取一个小于数组数的整数x作为第一个增量,把文件的全部记录分成x个组。
  2. 所有距离为x的倍数的值在同一组里,然后进行直接插入排序,变成有序序列。
  3. 取一个小于x的 x1 作为第二个增量,重复上述分组和排序,直到增量为1。
    注:当增量为1时,相当于所有记录放在同一组里进行直接插入排序

来自百度
假设有一组{70,30,40,10,80,20,90,100,75,60,45}无序序列

第一趟:增量gap为3时,即距离为3的元素放在一组,可以分成3组,分别是{70,10,90,60},{30,80,100,45},{40,20,75},按照直接插入排序对每个组进行排序。
第二趟:gap变成了2,接着和第一趟一样,最后也是按照直接插入排序对每个组进行排序。
第三趟:gap为1,后续操作也是如此…

3.代码实现

代码如下:

#include<stdio.h>
#define num 12
void ShellSort(int* a, int n)
{
	int gap = n;	
	while (gap > 1)
{
	gap = gap / 3 + 1; 
		for (int i = 0; i < gap; i++)
		{
			for (int j = i; j < n - gap; j += gap)
			{
				int end = j;
				int x = a[end + gap];
				while (end >= 0)
				{
					if (a[end] > x)
					{
						a[end + gap] = a[end];
						end -= gap;
					}
					else break;
				}
				a[end + gap] = x;
			}
		}
	}
}
int main()
{
	int arr[num] = { 3,1,4,5,2,7,9,0,8,10,11,6 };
	printf("初始序列:\n");
	for (int i = 0; i < num; i++)
	{
		printf("%d ", arr[i]);
	}
	ShellSort(arr, num);
	printf("\n排序后序列\n");
	for (int i = 0; i < num; i++)
	{
		printf("%d ", arr[i]);
	}
}

运行结果:
在这里插入图片描述

注:插入排序是排序的开始,各位努力学习的IT人员们,一起加油努力哦。祝各位学业有成,财源滚滚。
---------来自菜鸟TQ02的祝福语

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

tq02

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值