排序算法大全——插入排序

一、排序算法介绍 :

在计算机科学的世界里,排序无疑是最基础、最核心的议题之一。从数据库的高效查询,到搜索引擎对海量信息的整理,再到我们手机通讯录中按字母顺序排列的联系人,排序算法的身影无处不在。它就像一位无形的整理师,将杂乱无章的数据元素,按照某种特定的顺序(如数字大小、字母先后)重新排列,从而为后续的数据处理和分析奠定坚实的基础。**那么,面对不同的场景,我们该如何选择合适的排序算法?它们背后又隐藏着怎样精妙的智慧与效率的博弈?**本篇博客将带您深入探索排序算法的奇妙世界。

二、排序分类:

本篇博客主要是基于C语言来介绍一些内部排序算法大全包括:插入排序(直接插入排序、折半插入排序、希尔排序)、交换排序(冒泡排序、快速排序)、选择排序(简单选择排序、堆排序)、归并排序、基数排序。

而本篇博客主要讲解插入排序的过程及其对于算法代码

三、插入排序:

插入排序归根结底其实就是将一组要排序的数按照规则便利,每次便利后将比较完的数依次归纳到一个区间,而这个区间是由这些已经比较完的数组成的有序区间

1、直接插入排序:

直接插入排序就是从前往后依次便利然后将便利的数组成一个有序序列的排序:

比如:3,1,0,9,23,11

第一趟:(1,3),0,9,23,11(比较3,1,此时1,3构成一个有序序列)

第二趟:(0,1,3),9,23,11(比0与有序序列,从0与3比较,再与1比较)

第三趟:(0,1,3,9),23,11

......

代码展示:

cpp 复制代码
//插入排序的总体思想就是按顺序依次将每个数插入它前面的这个有序序列当中
//直接插入排序
void InsertSort(int a[], int n) {
	for (int i = 1; i < n; i++) {
		if (a[i] < a[i - 1])
		{
			int j = i - 1;//i-1是有序数据的第一个元素,比就是拿temp与j指向的元素开始比
			int temp = a[i];//将要插入的元素先放入一个临时变量中
			do {
				a[j + 1] = a[j];
				j--;
			} while (j >= 0 && temp < a[j]);//顺序不能变不然会奔溃
			a[j + 1] = temp;
		}
	}
}

这个代码有几个关键:

第一:比较时若是比有序序列最后一个数大,则不需要比较后面的数,直接插入到有序序列中,若是小则还需要继续往前比较其它数直到满足大于时候。

第二:因为首次比较后不需要再和这个数比较了所以使用do while函数比较好,可以直接与后面元素继续比较,少比较一次。

第三:插入不是简单的交换,而是将要插入位置之后所有元素后移一位再直接插入。

2、折半插入排序:

折半插入排序与直接插入排序的区别 主要在于如何与有序序列比较,直接插入排序是依次与有序序列的元素按照顺序排序,而折半插入排序是利用折半也就是二分的思想来与要插入的数比较。

二分的思想:我们一般取中间一个数来比较(int mid = (left + right) / 2;)

比如:3,1,0,9,23,11

第一趟:(1,3),0,9,23,11

第二趟:(0,1,3),9,23,11(这次当中,第一次比较的是将0与1比较而不是和3,因为此时有序序列的下标为0和1,它折半向下取整就为第0位置,也就是数字1,很明显时间复杂度可能会减小)

第三趟:(0,1,3,9),23,11(此时先将9与1比较,再将9与3比较,比较两次,但是直接插入只需要比较一次,所以要是说折半插入排序一定比直接插入要好,这是个错误说法)

第四躺:(0,1,3,9,23),11

......

cpp 复制代码
//折半插入排序
void BinaryinsertSort(int a[], int n)
{
	for (int i = 1; i < n; i++) {
		if (a[i] < a[i - 1])
		{
			int temp = a[i];
			int left = 0, right = i - 1;
			while (left <= right)
			{
				int mid = (left + right) / 2;
				if (temp < a[mid])
					right = mid - 1;
				else
					left = mid + 1;
			}
			for (int j = i - 1; j >= left; j--) {
				a[j + 1] = a[j];
			}
			a[left] = temp;//此时left=right
		}
	}
}

3、希尔排序:

希尔排序它的思想主要是在遍历整个序列时候采用一种"差辈"的比,但是在区间内仍然是直接插入,也就是寻找一个每次要寻找的d,这个d一般是由表长的一半组成,然后比较下标为:

第一趟:d=表长/2

0,d,2d;

1,1+d,2+d;

2,2+d,3+d

...直到便利所有

第二趟:d=d/2

0,d,2d;

1,1+d,2+d;

2,2+d,3+d

.....

直到d=1时最后一趟排序完成

cpp 复制代码
//希尔排序
void shellsort(int a[], int n)
{
	for (int d = n / 2; d >= 1; d /= 2) {
		for (int i = d; i < n; i++) //这里容易错要记住
		{
			if (a[i] < a[i - d]) {
				int j = i - d;
				int temp = a[i];
				do {
					a[j + d] = a[j];
					j -= d;
				} while (j >= 0 && temp < a[j]);
				a[j + d] = temp;
			}
		}
	}
}
相关推荐
Тиё Сиротака1 小时前
红包分配算法的严格数学理论与完整实现
算法
potato_may2 小时前
链式二叉树 —— 用指针构建的树形世界
c语言·数据结构·算法·链表·二叉树
java修仙传3 小时前
每日一题,力扣560. 和为 K 的子数组
算法·leetcode
ada7_3 小时前
LeetCode(python)——148.排序链表
python·算法·leetcode·链表
点云SLAM3 小时前
点云配准算法之-Voxelized GICP(VGICP)算法
算法·机器人·gpu·slam·点云配准·vgicp算法·gicp算法
资深web全栈开发5 小时前
LeetCode 3625. 统计梯形的数目 II
算法·leetcode·组合数学
橘颂TA5 小时前
【剑斩OFFER】算法的暴力美学——外观数列
算法·leetcode·职场和发展·结构与算法
Liangwei Lin5 小时前
洛谷 P1434 [SHOI2002] 滑雪
算法
c#上位机5 小时前
halcon图像增强之自动灰度拉伸
图像处理·算法·c#·halcon·图像增强
rit84324995 小时前
压缩感知信号恢复算法:OMP与CoSaMP对比分析
数据库·人工智能·算法