【数据结构】常见的排序算法 -- 插入排序

🫧个人主页: 小年糕是糕手

💫个人专栏:《数据结构(初阶)》** 《C/C++刷题集》 《C语言》**

🎨你不能左右天气,但你可以改变心情;你不能改变过去,但你可以决定未来!



目录

一、直接插入排序

1.1、算法思想

1.2、代码实现

二、希尔排序

2.1、算法思想

2.2、代码实现

2.3、时间复杂度计算


一、直接插入排序

直接插入排序是一种简单的插入排序法,其基本思想是:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列。

举一个生活中的例子:我们玩的扑克牌游戏,我们整理牌的时候采用的就是一个插入排序。

1.1、算法思想

当插入第 i(i >= 1) 个元素时,前面的 arr[0],arr[1],...,arr[ i - 1 ]已经排好序,此时用arr[ i ]的排序码与 arr[ i - 1],arr[ i - 2 ],...的排序码顺序进行比较,找到插入位置即将 arr[ i ]插入,原来位置上的元素顺序后移。

1.2、代码实现

cpp 复制代码
void InsertSort(int* arr, int n)
{
	for (int i = 0; i < n - 1; i++)
	{
		int end = i;
		int tmp = arr[end + 1];
		while (end > 0)
		{
			if (arr[end] > tmp)
			{
				arr[end + 1] = arr[end];
				end--;
			}
			else
			{
				break;
			}
		}
		arr[end + 1] = tmp;
	}
}

直接插入排序的特性总结

  1. 元素集合越接近有序,直接插入排序算法的时间效率越高
  2. 时间复杂度:O (N^2)
  3. 空间复杂度:O (1)

注意:当给定的数组接近有序时我们的时间复杂度会接近于O(N)但是不会真正达到

二、希尔排序

希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数(通常是gap = n / 3 + 1),把待排序文件所有记录分成各组,所有的距离相等的记录分在同一组内,并对每一组内的记录进行排序,然后gap = gap / 3 + 1得到下一个整数,再将数组分成各组,进行插入排序,当gap = 1时,就相当于直接插入排序。

它是在直接插入排序算法的基础上进行改进而来的,综合来说它的效率肯定是要高于直接插入排序算法的。

2.1、算法思想

  1. 确定初始步长选择一个小于数组长度的初始步长(如初始步长 = 数组长度 ÷ 2,后续逐步减半,直到步长为 1)。步长的选择直接影响排序效率,常见的有 "折半步长""Hibbard 步长" 等。
  2. 分组插入排序按当前步长将数组分为多个子组,每个子组由 "间隔为步长的元素" 组成(例如步长为 5 时,第 1、6、11... 个元素为一组,第 2、7、12... 个元素为另一组)。对每个子组分别执行插入排序,让子组内部变得有序。
  3. 逐步缩小步长并重复每次将步长缩小(如折半为原来的 1/2),重复 "分组插入排序" 操作。当步长缩小到 1 时,整个数组变为一个子组,执行最后一次插入排序,此时数组已接近有序,插入排序的效率会极高

2.2、代码实现

cpp 复制代码
void ShellSort(int* arr, int n)
{
	int gap = n;
	while (gap > 1)
	{
		//推荐写法:除3 
		gap = gap / 3 + 1;

		for (int i = 0; i < n - gap; i++)
		{
			int end = i;
			int tmp = arr[end + gap];
			while (end >= 0)
			{
				if (arr[end] > tmp)
				{
					arr[end + gap] = arr[end];
					end = end - gap;
				}
				else
				{
					break;
				}
			}
			arr[end + gap] = tmp;
		}
	}
}

希尔排序的特性总结

  1. 希尔排序是对直接插入排序的优化。
  2. 当 gap > 1 时都是预排序,目的是让数组更接近于有序。当 gap == 1 时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。

2.3、时间复杂度计算

希尔排序的时间复杂度估算:

外层循环外层循环的时间复杂度可以直接给出为:O(log2 ​n) 或者 O(log3 ​n),即O(log n)

内层循环

希尔排序时间复杂度不好计算,因为 gap 的取值很多,导致很难去计算,因此很多书中给出的希尔排序的时间复杂度都不固定。《数据结构(C语言版)》--- 严蔚敏书中给出的时间复杂度为:

相关推荐
我先去打把游戏先3 小时前
ESP32C3开发指南(基于IDF):console控制台命令行交互功能
笔记·嵌入式硬件·mcu·物联网·学习·esp32·交互
星释3 小时前
Rust 练习册 4:Deref trait 与智能指针
开发语言·后端·rust
心随雨下3 小时前
Java中将System.out内容写入Tomcat日志
java·开发语言·tomcat
墨染点香3 小时前
LeetCode 刷题【142. 环形链表 II】
算法·leetcode·链表
海琴烟Sunshine3 小时前
leetcode 263. 丑数 python
python·算法·leetcode
信仰_2739932433 小时前
Guava Cache淘汰算法
算法·guava
User_芊芊君子3 小时前
【LeetCode 经典题解】:队列与栈的双向模拟——从原理到代码详解
linux·redis·leetcode
AI视觉网奇3 小时前
yolo 获取异常样本 yolo 异常
开发语言·python·yolo
散峰而望3 小时前
C++入门(二) (算法竞赛)
开发语言·c++·算法·github