【C语言】排序算法——希尔排序以及插入排序 ——详解!!!

【C语言】排序算法------希尔排序以及插入排序详解

  • 前言
  • [一 、插入排序](#一 、插入排序)
    • [1. 视频演示](#1. 视频演示)
    • [2. 算法思想](#2. 算法思想)
    • [3. 实现思路](#3. 实现思路)
    • [4. 代码演示](#4. 代码演示)
  • [二 、希尔排序](#二 、希尔排序)
  • 结语

前言

在学习循环的时候,我们学习到了冒泡排序这个算法
那么,除了冒泡排序,还有什么排序算法呢?
今天给大家带来的是插入排序以及希尔排序

一 、插入排序

1. 视频演示

首先给大家看一段视频,让大家先看看插入排序是怎么运行的

插入排序演示

2. 算法思想

我们可以从视频里看见,插入排序就像是我们打扑克牌一样,一张一张插入到了有序队列
每次都有一个数据 x(标红的)要跟前面的数据一一比大小
若 x 比前一个数据小,则 x 就再向前比较
若 x 比前一个数据大,则 x 就插入到这个数据的后面

3. 实现思路

由视频可知,数据 x(标红的)前面的序列都是有序的,故每一次只需要将 x 插入其中即可

  • 第一步

我们给定下标范围【0,end】区间是有序的,tmp为要插入的数据的值,故tmp为下标为end + 1所对应的值

  • 第二步

将下标为end所对应的值与tmp比较
tmp比前一个数据小,则tmp就再向前一个数比较
tmp比前一个数据大,则tmp就插入到这个数据的后面

  • 第三步

循环遍历整个数组,直到数组全部插入进去

4. 代码演示

c 复制代码
// 插入排序
void InsertSort(int* a, int n)
{
	for (int i = 0; i < n - 1; i++)
	{
		int end = i;
		int tmp = a[end + 1];
		while (end >= 0)
		{
			if (tmp < a[end])
			{
				a[end + 1] = a[end];
				end--;
			}
			else
			{
				break;
			}
		}
		a[end + 1] = tmp;
	}
}

二 、希尔排序

1. 视频演示

首先给大家看一段视频,让大家先看看希尔排序是怎么运行的

希尔排序视频演示

2. 算法思想

当你看完视频,你也许就会发现希尔排序和插入排序很相似

只不过,希尔排序相当于间隔插入排序 n 次
而每一次都越来越接近有序数组,直到最后一次排成有序

3. 实现思路

那该怎么实现呢?

(1)分组

  • 第一步:分组

由视频可知,每次排序并不是一个一个排,而是每间隔几个数据成一组来排序
一组一组排,这组排完就到下一组,直到全部排完

这里先假设分成3组数据进行排序,也就是每隔2个数据成一组

如图:

(2)预排序

  • 第二步:预排序

分成了几组后,每一组就开始插入排序,称为预排序

插入排序前面讲了,就不赘述了

代码演示:
( gap 就是被分成了几组)

c 复制代码
int gap = n;
while (gap > 1)
{
	gap = 3;
	for (int i = 0; i < n - gap; i++)
	{
		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)最终排序

  • 第三步:最终排序

现在,在排序完三组数据后,我们的数组已经很接近有序
所以现在只需要用插入排序排最后一次收尾就行了

这里就不进行代码演示了,就是一个普通的插入排序

(4)gap的取值

  • 第四步:gap的取值

、前面我们的代码中 gap 的取值定为了 3 ,但是这不可能对于每个数组都适应

那么该如何给 gap 来取值呢?
根据科学的实验,发现当gapn / 3时,排序最快
所以,在排序的过程中,gap 的值是不断发生变化的
、到这里,可能已经有人发现了,刚刚写的预排序和前面写的插入排序几乎一摸一样
只是将 1 变成了 gap
>其实,当gap1时,就是普通的插入排序

那么我们能不能设计一个循环,既能在排序的过程中满足gap的动态变化,又能使gap的最后一次取值为 1 呢?

所以我们可以有一些改进,在函数外面再套一层循环:
int gap = n;
while (gap > 1)
{
gap = gap / 3 + 1;
............
............//这里省去代码
}

这样,gap能够很好的动态变化,且最后一次循环的gap值为1,恰好能完成一次普通的插入排序

4. 代码演示

代码演示:

c 复制代码
// 希尔排序
void ShellSort(int* a, int n)
{
	int gap = n;
	while (gap > 1)
	{
		gap = gap / 3 + 1;
		for (int i = 0; i < n - gap; i++)
		{
			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;
		}
	}
}

结语

OK,本期的排序算法详解到这里就结束了

若内容对大家有所帮助,可以收藏慢慢看,感谢大家支持

本文有若有不足之处,希望各位兄弟们能给出宝贵的意见。谢谢大家!!!

新人,本期制作不易希望各位兄弟们能动动小手,三连走一走!!!

支持一下(三连必回QwQ)

相关推荐
Zhan8611244 分钟前
数据接口的序列号机制与丢包检测:西班牙行情数据IBEX指数实时行情接入笔记
大数据·数据结构·笔记·区块链
菜鸡爱玩2 小时前
线性代数矩阵相乘
线性代数·算法·矩阵
devilnumber6 小时前
Java 递归算法 详解 + 核心要点 + 实战运用 + 避坑指南
java·开发语言·算法
unicrom_深圳市由你创科技7 小时前
哪些控制逻辑应该放在 PLC,哪些放在上位机?
c++
‎ദ്ദിᵔ.˛.ᵔ₎8 小时前
双指针、滑动窗口、前缀和、二分查找 算法
算法
顾北顾8 小时前
多头注意力机制
人工智能·深度学习·算法
H178535090968 小时前
SolidWorks_基于草图的实体特征20_特征错误排查
算法·3d建模·solidworks
hujinyuan201608 小时前
2025年12月中国电子学会青少年机器人技术等级考试试卷(二级) 真题+答案
人工智能·算法·机器人
玖玥拾8 小时前
C/C++ 基础笔记(十三)继承
c语言·c++·继承
闪闪发亮的小星星8 小时前
开普勒三大定律
笔记