6.1排序——插入排序与希尔排序

news2024/12/26 20:41:17

本篇博客来梳理两种常见排序算法:插入排序与希尔排序
常见的排序算法如图
常见的排序算法
写排序算法的原则:先写单趟,再写整体

一、直接插入排序

1.算法思想

先假定第一个数据有序,把第二个数据插入;再假设前两个数据有序,把第三个数据插入…以此类推,直到整个序列有序

2.具体操作(以排成升序为例)

(1)单趟:针对单个数据

假设[0,end]有序,处理end+1处数据(用tmp存起来,原因:挪数据的时候会覆盖),依次与前面的数比,用while循环控制

  • tmp更大:插入
  • tmp更小:挪数据,同时–end
    插入排序动图

程序结构如下

while(end>=0)
{
	if(tmp更小)
		//挪数据;
		--end;
	else
		break;
}
//插入数据

注意:如果处理最小的数据,end会是-1(数据要插入到a[0]的位置)

在这里插入代码片

(2)单趟变整体:用for循环控制end从0->n-2

end最大是n-2的原因:要动end+1处数据,保证不越界

(3)具体代码实现

// 直接插入排序(假设排成升序)
void InsertSort(int* a, int n)
{
	for (int i = 0; i < n-1; i++)
	{
		//单趟
		int end = i;//end最大是n-2
		int tmp = a[end + 1];//end+1最大是n-1
		while (end >= 0)
		{
			if (tmp < a[end])
			{
				a[end + 1] = a[end];//往后挪数据
				--end;
			}
			else
			{
				break;
			}
		}
		a[end + 1] = tmp;//插入数据
	}
}

3.特性总结

(1)时间复杂度:o(N²)
(2)空间复杂度:o(1)
(3)稳定性:稳定
(4)元素集合越接近有序,算法效率越高

二、希尔排序(缩小增量排序)

1.算法思想

先对整个序列进行预排序,使数组接近有序,最后进行直接插入排序的时候数组已经很接近有序,因此可以大大提升算法的效率

2.具体操作(以排成升序为例)

(1)第一步:预排序(让数组接近有序)——本质:gap>1的插入排序

取gap==3,把整组数据分成了3组
①单趟:处理一次之后黄色分组边界上的数字(9,5,8,5)就有序了,相当于对9,5,8,5进行插入排序,只不过中间跨越了gap这么多数据

//以下两层循环实际上就是直接插入排序的变种,把1换成了gap
for (int j = 0; j < n - gap; j+=gap)
{
	//单趟
	int end = j;
	int tmp = a[end + gap];
	while (end >= 0)
	{
		if (tmp < a[end])
		{
			a[end + gap] = a[end];
			end -= gap;
		}
		else
		{
			break;
		}
	}
	a[end + 1] = tmp;
}

对比一下插入排序的代码,就是把1换成了gap
②单趟变整体——处理红色和蓝色的组别(在外面再用一层for循环控制)

//以下两层循环实际上就是直接插入排序的变种,把1换成了gap
for(int i = 0;i < gap; i++)
{
	for (int j = 0; j < n - gap; j+=gap)
	{
		//单趟
		int end = j;
		int tmp = a[end + gap];
		while (end >= 0)
		{
			if (tmp < a[end])
			{
				a[end + gap] = a[end];
				end -= gap;
			}
			else
			{
				break;
			}
		}
		a[end + 1] = tmp;
	}
}

希尔排序1
希尔排序2
三层循环看起来太多了,有时候可能会不好分析,于是就可以对(1)(2)进行优化
上面代码的逻辑:先处理黄色组,再处理红色组,最后处理蓝色组,其中对红色组和蓝色组的处理需要在最外层套入第三层循环
优化操作:“每组并着走”,而不是像上面那样“一组一组来”,把最外层循环去掉,然后第二层循环中j+=gap改成j++,处理顺序变成:黄->红->蓝->黄->红->蓝…

		for (int j = 0; j < n - gap; j++)//j+=gap改成了j++
		{
			//单趟
			int end = j;
			int tmp = a[end + gap];
			while (end >= 0)
			{
				if (tmp < a[end])
				{
					a[end + gap] = a[end];
					end -= gap;
				}
				else
				{
					break;
				}
			}
			a[end + 1] = tmp;
		}

(2)第二步:插入排序——gap==1的插入排序

注意:gap越大,大的就更快跳到后面,小的就更快跳到前面,但不那么有序
gap越小,跳得更慢,但更有序
所以:gap要不断变小,直到最后变成1,这样最终插入排序处理的序列就更有序——再来一层循环控制gap(此处对上面优化版的代码进行操作,否则四层循环看着都晕了)

常见调整方式:gap=gap/3+1(保证最后一个gap是1)
此处没有单独写插入排序的原因:gap最后会迭代成1,此时执行的就是直接插入排序
至此,完整的希尔排序代码就出来了

(3)具体代码实现

// 希尔排序(假设排成升序)
void ShellSort(int* a, int n)
{
	//预排序
	int gap = 3;
	while(gap > 1)//外面再来一层循环,实现gap的迭代
	{
		gap = gap / 3 + 1;//保证最后一个gap是1
		//以下两层循环实际上就是直接插入排序的变种,把1换成了gap
		for (int j = 0; j < n - gap; j++)
		{
			//单趟
			int end = j;
			int tmp = a[end + gap];
			while (end >= 0)
			{
				if (tmp < a[end])
				{
					a[end + gap] = a[end];
					end -= gap;
				}
				else
				{
					break;
				}
			}
			a[end + 1] = tmp;
		}
	}
}

3.特性总结

(1)希尔排序是对直接插入排序的优化
(2)gap>1时是预排序,目的是让数组更接近有序。当gap==1的时候,数组已经接近有序了,此时进行直接插入排序就会很快,性能得到了优化
(3) 希尔排序时间复杂度计算难度大,限于本人水平,只能在这里写个结论,大约是o(N^1.3)
(4)稳定性:不稳定

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2114186.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

iOS剪贴板同步到Windows剪贴板(无需安装软件的方案)

摘要 剪贴板同步能够提高很多的效率&#xff0c;免去复制、发送、复制、粘贴的步骤&#xff0c;只需要在手机上复制&#xff0c;就可以直接在电脑上 ctrlv 粘贴&#xff0c;这方面在 Apple 设备中是做的非常好的&#xff0c;Apple 设备之间的剪贴板同步功能&#xff08;Univer…

2024整理 iptables防火墙学习笔记大全_modepro iptables

Iptables名词和术语 2iptables表&#xff08;tables&#xff09;和链&#xff08;chains&#xff09; 2表及其链的功能 2  Filter表 2  NAT表 2  MANGLE表 2iptables的工作流程 3iptables表和链的工作流程图 3 二、 iptables实战应用 4iptables命令参数详解 4  iptable…

Python基础part1

Python基础 语法 字面量 数字 整数浮点复数布尔 字符串列表 list元组 Tuple集合 Set字典 Dictionary 注释 单行# 单行注释的内容多行“”“ 多行注释的内容 ”“” 单行注释#后要加一个空格再写注释 变量 变量无类型&#xff0c;但数据有类型 语法&#xff1a; 变量名 …

java黑马微项目

1 飞机票 代码实现&#xff1a; import java.util.Scanner; public class F1 {public static void main(String[] args) {Scanner input new Scanner(System.in);System.out.print("请输入票价&#xff1a; ");double jia input.nextDouble();System.out.print(&…

培训第九周(部署k8s基础环境)

一、前期系统环境准备 1、关闭防火墙与selinux [rootk8s-master ~]# systemctl stop firewalld[rootk8s-master ~]# systemctl disable firewalldRemoved symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.Removed symlink /etc/systemd/system/dbus-o…

快速格式化和格式化的区别有哪些?

磁盘通常需要格式化才能正常使用&#xff0c;通过格式化&#xff0c;磁盘结构才能被操作系统正确识别。磁盘格式化分为快速格式化和格式化&#xff08;完全格式化&#xff09;&#xff0c;它们都是格式化的方法&#xff0c;下面是它们的详细区别。 磁盘快速格式化和格式化的区别…

2024 年高教社杯全国大学生数学建模竞赛B题第三问详细解题思路(终版)

示例代码&#xff1a; import numpy as np import pandas as pd# 参数设定 params {m: 8, # 零配件数量n: 2, # 半成品数量p: [0.10, 0.10, 0.10, 0.10, 0.10, 0.10, 0.10, 0.10], # 零配件次品率c: [2, 8, 12, 2, 8, 12, 8, 12], # 购买单价d: [1, 1, 2, 1, 1, 2, 1, 2]…

个性化阅读体验:Spring Boot驱动的图书推荐系统

1 绪论 1.1研究背景 随着网络不断的普及发展&#xff0c;图书个性化推荐系统依靠网络技术的支持得到了快速的发展&#xff0c;首先要从学生的实际需求出发&#xff0c;通过了解学生的需求开发出具有针对性的首页、图书信息、好书推荐、留言反馈、个人中心、后台管理功能&#x…

文本分类场景下微调BERT

How to Fine-Tune BERT for Text Classification 论文《How to Fine-Tune BERT for Text Classification?》是2019年发表的一篇论文。这篇文章做了一些实验来分析了如何在文本分类场景下微调BERT&#xff0c;是后面网上讨论如何微调BERT时经常提到的论文。 结论与思路 先来看…

19:HAL—-DAC

一&#xff1a;介绍 1&#xff1a;简历 2&#xff1a;简图 F1,F4,F7的DAC框架图都一样。 触发源&#xff1a; 宏定义补全及解释 #define DAC_TRIGGER_NONE 0x00000000UL /*!< 转换是自动的&#xff0c;一旦DAC1_DHRxxxx寄存器被加载&#xff0c;不由外部触发 */ #define …

ctfshow-php特性(web123-web150plus)

​web123 <?php error_reporting(0); highlight_file(__FILE__); include("flag.php"); $a$_SERVER[argv]; $c$_POST[fun]; if(isset($_POST[CTF_SHOW])&&isset($_POST[CTF_SHOW.COM])&&!isset($_GET[fl0g])){if(!preg_match("/\\\\|\/|\~|…

AI模型的未来之路:全能与专精的博弈与共生

人工智能(AI)领域正迅速发展,伴随着技术的不断进步,AI模型的应用范围也在不断扩展。当前,AI模型的设计和使用面临两个主要趋势:全能型模型和专精型模型。这两者之间的博弈与共生将塑造未来的AI技术格局。本文将从以下七个方面探讨AI模型的未来之路,并提供实用的代码示例…

软考-高级架构师Keywords(上半部分)

概述 本文用于备考时自查知识点掌握情况&#xff0c; 知识点只以关键词方式提点出来&#xff0c;算是对照考纲的细碎化转化。 太简单的知识点不会收录。特别适合 通过中级-软件设计师的同学 / 八股文爱好者 / 408选手 计算机硬件 码距&#xff1a;改变n位成为另一个编码所需要…

业务资源管理模式语言09

示例&#xff1a; 图13 表示了QuoteTheMaintenance 模式的一个实例&#xff0c;在汽车修理店系统中&#xff0c;其中“Vehicle”扮演“Resource”&#xff0c;“Repair Quotation”扮演“Maintenance Quotation”&#xff0c;“Repair shop branch”扮演“Source-party”&…

halcon图像怎么显示在我们指定的区域

要想搞明白这个问题,首先我们要了解句柄的传递关系. halcon生成图像,会产生一个图像句柄,只要把该句柄传递给我们需要显示的组件就可以了. 简单说,就是一个句柄的传递关系. 下面这个例子简单说明句柄传递关系: 我们获取一个图像控件的句柄,把图像句柄传递给halcon的图像窗口句…

BN于神经网络调优

目录 一:神经网络调优 1.算法层面: 2.网络层面 二:调参技巧: 2.合理的参数设置: 3.运行: 三:批标准化(Batch Normalizetion) 1.批标准化公式: 2.过程图: 3.为什么标准化能够是优化过程变得简单: 一:神经网络调优 参数调优也称为超参数调优 1.算法层面…

JS手写实现深拷贝

手写深拷贝 一、通过JSON.stringify二、函数库lodash三、递归实现深拷贝基础递归升级版递归---解决环引用爆栈问题最终版递归---解决其余类型拷贝结果 一、通过JSON.stringify JSON.parse(JSON.stringify(obj))是比较常用的深拷贝方法之一 原理&#xff1a;利用JSON.stringif…

刘诗诗现身纽约两场活动,演绎极具松弛感的优雅,生图状态绝美

近期&#xff0c;纽约迎来了时装周&#xff0c;还有奢侈品牌活动陆续举办&#xff0c;演员刘诗诗也现身部分活动现场&#xff0c;以绝佳好状态收获大量关注和好评。 纽约时间9月4日&#xff0c;刘诗诗现身Bobbi Brown芭比波朗「IN MY SKIN GLOBALEVENT」活动&#xff0c;身穿裸…

ubuntu 和windows用samba服务器实现数据传输

1&#xff0c;linux安装samba服务器 sudo apt-get install samba samba-common 2&#xff0c;linux 配置权限&#xff0c;修改目录权限&#xff0c;linux下共享的文件权限设置。 sudo chmod 777 /home/lark -R 3. 添加samba用户 sudo smbpasswd -a lark 4&#xff0c;配置共享…

【AcWing】853. 有边数限制的最短路(bellman-ford贝尔曼福特算法)

存储&#xff1a; 这个算法存边不一定要写成邻接表&#xff0c;随便存&#xff0c;只要能遍历到所有边即可&#xff0c;结构体数组。 过程&#xff1a; 负权边、负权回路&#xff1a; 贝尔曼福特算法处理有负权边的图。(注意&#xff0c;有负权回路的话&#xff0c;最短路径就不…