初阶数据结构排序之插入排序

排序01

插⼊排序

基本思想

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

实际中我们玩扑克牌时,就⽤了插⼊排序的思想

直接插⼊排序

当插⼊第 i(i>=1) 个元素时,前⾯的 array0,array1,...,arrayi-1 已经排好序,此时 ⽤ arrayi 的排序码与 arrayi-1,arrayi-2,... 的排序码顺序进⾏⽐较,找到插⼊位置 即将 arrayi 插⼊,原来位置上的元素顺序后移

InsertSort.h

C 复制代码
#pragma once
#include <stdio.h>

void InsertSort(int* arr, int n);

void Print(int* arr, int n);

InsertSort.c

C 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include "InsertSort.h"
 
void InsertSort(int* arr, int n)
{
	//外层循环控制内部要进行多少次
	//n-1是因为end+1的时候,end=n的话,会造成越界
	for (int i = 0; i < n - 1; i++)
	{
		//end表示有序数组的最后一位
		int end = i;
		//tmp表示有序数组的下一位
		int tmp = arr[end + 1];
		while (end >= 0)
		{
			if (arr[end] > tmp)
			{
				arr[end + 1] = arr[end];
				//这是从后往前进行比较
				end--;
			}
			//如果顺序不用变动,就跳出循环
			else
			{
				break;
			}
		}
		//最后循环出来得到的结果
		arr[end + 1] = tmp;
	}
}
void Print(int* arr, int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d", arr[i]);
	}
	printf("\n");
}

Test.c

C 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include "InsertSort.h"
int main()
{
	int arr[] = { 3,4,2,1,6,5,7,9,8 };
	int n = sizeof(arr) / sizeof(arr[0]);
	InsertSort(arr, n);
	Print(arr, n);
	return 0;
}

直接插⼊排序的特性总结

1.元素集合越接近有序,直接插⼊排序算法的时间效率越⾼

2.时间复杂度:O(N^2)

3.空间复杂度:O(1)

注意点:最不好的情况是降序排序的时候

那么我们该怎样进一步优化呢,接下来我们来看希尔排序

希尔排序

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

它是在直接插⼊排序算法的基础上进⾏改进⽽来的,综合来说它的效率肯定是要⾼于直接插⼊排序算 法的。

代码如下:

ShellSort.h

C 复制代码
#pragma once
#include <stdio.h>

void ShellSort(int* arr, int n);
void Print(int* arr, int n);

ShellSort.c

C 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include "ShellSort.h"

void ShellSort(int* arr, int n)
{
	int gap = n;
	//不能够等于1,等于1的时候会造成死循环,因为下面的+1是保证最后gap=1的
	while (gap>1)
	{
		gap = gap / 3 + 1;//保证最后gap=1
        //使用i++是分成三组,分别比较每组的第一个大小,再比较两组的第二个,这样时间复杂度进一步降低
		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 -= gap;
				}
				else
				{
					break;
				}
			}
			arr[end + gap] = tmp;
		}
	}
}
void Print(int* arr, int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d", arr[i]);
	}
	printf("\n");
}

Test.c

C 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include "ShellSort.h"

int main()
{
	int a[] = { 2,1,4,3,5,6,8,7,9,10 };
	int n = sizeof(a) / sizeof(a[0]);
	ShellSort(a, n);
	Print(a, n);
	return 0;
}

希尔排序的特性总结

1.希尔排序是对直接插⼊排序的优化。

2.当 gap > 1 时都是预排序,⽬的是让数组更接近于有序。当 gap == 1 时,数组已经接近有序 的了,这样就会很快。这样整体⽽⾔,可以达到优化的效果。

更进一步来说就是:

1.预排序 gap>1

2.直接插入排序 gap=1

小的靠前,大的靠后

相关推荐
白帽攻防录5 小时前
SRC 挖洞:PostScript 打印机驱动双 RCE,打印服务器怎么变成内网跳板
开发语言·网络安全·php·内网安全
十年Java程序媛5 小时前
Java枚举Enum完整教程|替代静态常量,开发与面试要点
java·开发语言·spring boot·后端·面试
2603_965148116 小时前
电商选品调研:通过关键词搜索API获取市场热销商品,结合商品详情API分析竞品卖点与定价
开发语言·数据库·人工智能·python·信息可视化
生态学者6 小时前
Global Change Biology | 森林越“步调一致”,反而越怕干旱?树木生长与叶片活动的同步之谜
大数据·人工智能·算法·r语言·微信公众平台
xixiaoyunya7 小时前
Python 异步编程入门:用 asyncio 轻松实现并发任务
开发语言·python·php
lsswear7 小时前
Agent 框架新手入门与实战部署指南
大数据·人工智能·算法
学逆向的7 小时前
C 循环结构的执行效率分析
c语言·开发语言·数据结构·网络安全
小坏讲微服务7 小时前
刚发布一个月的JDK 27,为什么我建议你立刻升级?
java·开发语言·spring boot·spring·架构·求职招聘·springboot4
Data analyse4568 小时前
rnweb 回放数据量太大怎么办?分片存储与断点续传的实现思路
前端·网络·算法·数据分析
打工仔折腾 AI9 小时前
用 Dashlet 把极空间 NAS 服务入口整理成统一导航首页的实践
java·开发语言·人工智能·后端·python·rpc·ai agent 实战