【数据结构】常见排序算法——常见排序介绍、插入排序、直接插入排序、希尔排序

news2024/10/7 17:31:35

文章目录

  • 1.排序的概念和应用
    • 1.1排序的概念
    • 1.2排序的运用
    • 1.3常见的排序算法
  • 2.常见的排序算法
    • 2.1插入排序
      • 2.1.1直接插入排序
      • 2.1.2希尔排序

1.排序的概念和应用

1.1排序的概念

  在计算机科学中,排序是将一组数据按照指定的顺序排列的过程。排序算法由于执行效率的不同可以分为多种不同的算法。

  通常情况下,排序算法可以分为两类,即内部排序和外部排序。内部排序是指数据全部加载到内存中进行排序,适用于数据量较小的情况,而外部排序则是指针对数据量较大的情况,需要利用外部存储设备(如磁盘)进行排序。在不同场景下,我们需要选择不同的排序算法来达到最佳的排序效果。

(1)排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。

(2)稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。

(3)内部排序:数据元素全部放在内存中的排序。

(4)外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。

1.2排序的运用

  排序算法被广泛应用于计算机程序中,用于对数据进行排序,以便更快、更方便地处理和查询数据。这些应用包括数据库、搜索引擎、数据分析、加密、财务管理、视频处理和游戏开发等领域。
在这里插入图片描述

  生活中很多地方都会有排序。
  
在这里插入图片描述

1.3常见的排序算法

在这里插入图片描述

2.常见的排序算法

2.1插入排序

  直接插入排序是一种简单的插入排序法,其基本思想是:

  插入排序特点:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列。

我们在玩扑克时,就运用到了插入排序:

在这里插入图片描述

2.1.1直接插入排序

  直接插入排序(Insertion Sort)是一种简单但有效的排序算法,其基本思想是将一个新元素插入到已排序好的元素序列中去。具体实现中,我们从第二个元素开始,将当前元素与前面已排序的元素进行比较,如果当前元素比前一个元素小,则将它插入前一个元素的前面,否则不做处理。如此以往,直到最后一个元素都被放入正确的位置为止。

  插入排序属于原地排序,只需要常数级别的额外空间。在处理小规模数据集时比较高效,但在处理大型数据集时会有些效率问题。它的时间复杂度为O(n2)但由于其常数项比冒泡排序和选择排序小,因此实际运行时比这些算法更快。插入排序是一种稳定排序算法,因为在排序过程中不涉及跳跃式的交换,所以相等元素的相对位置不会改变。

直接插入排序实现思想:

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

在这里插入图片描述


直接插入排序的实现:

  具体来说,这个函数的作用是对传入的数组a进行排序,数组中有n个元素。首先在外层循环中,从数组的第二个元素(索引为1)开始遍历,将其作为当前待排序的元素tmp,同时记录一个end指针指向当前已排序的最后一个元素所在的位置。

  在内层循环中,我们将tmp与end所指向的元素比较,如果tmp小于end所指向的元素,则将end所指向的元素后移一位,并向前移动end指针,继续在区间[0, end]中进行比较,直到找到tmp应该插入的位置。

  最后,将tmp插入到正确的位置,该插入位置为end + 1。

  这样,经过n-1次外层循环的排序操作后,数组a中的元素就按升序排列了。

void InsertSort(int* a, int n)
{
	for (int i = 1; i < n; i++)
	{
		int end=i-1;
		int tmp=a[i];
		//将tmp插入到[0,end]区间中,保持有序
		while (end >= 0)
		{
			if (tmp < a[end])
			{
				a[end + 1] = a[end];
				end--;
			}
			else
			{
				break;
			}
		}
		a[end + 1] = tmp;
	}
}

直接插入排序的特性总结:

(1)元素集合越接近有序,直接插入排序算法的时间效率越高;

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

(3)空间复杂度:O(1),它是一种稳定的排序算法;

(4)稳定性:稳定。

2.1.2希尔排序

  希尔排序(Shell Sort)是插入排序的一种变体,是一种针对插入排序进行优化的算法,也被称为“缩小增量排序”。希尔排序的基本思想是对待排序的序列进行分组,对于每个子序列应用直接插入排序算法进行排序,逐渐扩大分组的范围,同时逐步缩小增量,直到分组大小为1,完成排序。

  希尔排序通过先排序间隔较长的子序列,使得整个序列中的数据基本有序,这样在排序较短的子序列时就可以节省大量时间,从而提高整个排序的效率。希尔排序有许多种不同的递增序列选择方法,不同的算法实现之间可利用不同的增量序列。

  希尔排序的时间复杂度与其所选用的增量序列有关,最差情况下为O(n2)平均情况下为O(n1.3)左右。希尔排序属于不稳定排序,因为在大间隔排序时元素的相对位置可能会发生变化。

希尔排序法实现思想:

  先选定一个整数,把待排序文件中所有记录分成个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序。

在这里插入图片描述

希尔排序的实现:

  希尔排序的思想是先取一个间隔gap,将数组a分为若干个长度为gap的子序列,分别对这些子序列进行直接插入排序。然后逐渐缩小gap的值,重复以上操作,直至gap=1时,整个数组排序完成。

  代码中使用的增量序列是gap = gap / 3 + 1,也可选择其他增量序列,每次都将gap值缩小,直至其为1时排序结束。对于每个子序列,通过直接插入排序进行排序,不同之处是直接插入排序是对相邻的元素进行插入操作,而希尔排序的插入操作是对相距gap的元素进行插入。

  具体来看,对于每个间隔为gap的子序列,我们初始化end为i,记录待插入的元素tmp=a[i+gap],然后将tmp进行插入操作,找到合适的位置,使得end所在位置及之后的元素都向后移动gap个位置。插入排序的结束位置为0,整个操作过程和直接插入排序是类似的。

综上,希尔排序是通过先分组排序后逐步缩小元素间距,以达到提高排序效率的一种排序算法。

void ShellSort(int* a, int n)
{
	int gap = n;
	while (gap > 1)
	{
		//gap = gap/2;
		gap = gap / 3 + 1;

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

  我们可以简化上面的代码,使其减少一个循环,但复杂度不变:

  这段代码是标准的希尔排序的实现。它接受两个参数:一个整型数组a和数组的长度n。其中,数组a是待排序的对象,n表示数组a的元素个数。

  标准的希尔排序是将待排序的序列分成若干个子序列,对每个子序列进行插入排序,随后逐渐缩小子序列的长度,直到整个序列排序完成。关键点在于使用不同的增量gap来划分子序列,不同的增量选择方式会影响算法的时间复杂度。

  在该代码中,希尔排序的增量序列选择的策略是gap = n/2, n/4, n/8, … 直到gap=1。每次缩小增量gap之后,对每个子序列都进行一次插入排序。这样可以使得每个元素都能够尽可能快地移动到自己的正确位置上,以达到加速排序的目的。

  具体来看,每次对一个增量gap的子序列进行直接插入排序,我们选取增量gap之后,通过循环将整个数组分成了gap组。对于每个子序列,通过直接插入排序算法进行排序,在一次希尔排序中,相同的元素可能在多个子序列进行比较和赋值操作。

  通过多次迭代,不断缩小增量gap,在进行若干次间隔大的直接插入排序之后,我们最后得到的是一次增量为1的直接插入排序,此时整个序列的排序完成。

综上,标准的希尔排序算法是一种高效的排序算法,其时间复杂度和其所采用的增量序列有关,最优的情况下是O(n*log(n)),最差情况下是O(n^2)。

void ShellSort(int* a, int n)
{
	// gap > 1 预排序
	// gap == 1 直接插入排序
	int gap = n;
	while (gap > 1)
	{
		//gap /= 2;
		gap = gap / 3 + 1;

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

希尔排序的特性总结:

(1)希尔排序是对直接插入排序的优化。

(2)当gap > 1时都是预排序,目的是让数组更接近于有序。 当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。

(3)希尔排序的时间复杂度不好计算, 因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的希尔排序的时间复杂度都不固定。

(4)稳定性:不稳定。

 《数据结构(C语言版)》— 严蔚敏
在这里插入图片描述

这些就是数据结构中有关直接插入排序和希尔排序的简单介绍了😉
如有错误❌望指正,最后祝大家学习进步✊天天开心✨🎉

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

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

相关文章

01_爬虫基础知识和requests模块简介

爬虫基础知识 1、爬虫简介: 爬虫的作用:帮助我们把网站信息快速提取并保存爬虫的分类: 通用爬虫聚集爬虫爬虫的安全知识:目前来说,无明确法律规定,但每个官网都有自己的爬虫协议(网址后面加/robots.txt)爬虫的爬取流程: 1、获取网页2、提取信息3、保存数据2、爬虫必须…

分布式软件架构——远程服务调用

序言 “架构师”可以是做企业战略设计的架构师&#xff0c;也可以说做业务流程分析的架构师。 架构师视角特指软件系统中技术模型的系统设计者。 在做架构设计的时候&#xff0c;架构师应该思考哪些问题、可以选择哪些主流的解决方案和行业标准做法&#xff0c;以及这些主流方…

【自制C++深度学习框架】前言

KuiperCourse 介绍 此GitHub项目是一个初学者的深度学习框架&#xff0c;使用C编写&#xff0c;旨在为用户提供一种简单、易于理解的深度学习实现方式。以下是本项目的主要特点和功能&#xff1a; 计算图&#xff1a;使用计算图来描述深度学习模型的计算过程&#xff0c;利用计…

气球飘飘:用Java Swing创造令人心旷神怡的视觉奇观

✨博主&#xff1a;命运之光 ✨专栏&#xff1a;Java经典程序设计 前言&#xff1a;这篇博客在手机上打开可能会自动播放视频&#xff0c;视频有音乐&#xff0c;请及时关闭手机音乐哈&#x1f642; 目录 ✨导语 ✨引言 ✨简单介绍一下Javaswing这项技术简单介绍一下Javaswi…

简单的UDP网络程序·续写

该文承接文章 简单的UDP网络程序 对于客户端和服务端的基本源码参考上文&#xff0c;该文对服务器润色一下&#xff0c;并且实现几个基本的业务服务逻辑 目录 demo1 第一个功能&#xff1a;字典翻译 初始化字典 测试代码&#xff1a;打印 字符串分割 客户端修改 成品效果…

idea如何一个项目启动两个tomcat服务(不同端口)

目录 第一步&#xff1a;创建一个普通的springboot项目 第二步&#xff1a;编写一个controller代码&#xff0c;用来接收请求 第三步&#xff1a;复制服务&#xff0c;端口设置为8081 第四步&#xff1a;依次访问8080、8081两个服务进行测试 第一步&#xff1a;创建一个普通…

基于JavaWeb的保护动物管理系统设计与实现

摘要&#xff1a;随着全球一些稀有物种、野生动物日益稀少&#xff0c;保护动物已经成为全球多个国家开始重视并投入大量物力着手解决的重要课题。动物是大自然的产物&#xff0c;自然界是由许多复杂的生态系统构成的。有一种植物消失了&#xff0c;以这种植物为食的昆虫就会消…

easyExcel导入失败提示用户第几行有误并回滚数据

思路&#xff1a; 在controller定义一个map&#xff0c;将map传入excel监听器&#xff0c;在监听器中处理excel的数据&#xff0c;读取到某一行出现错误就将错误提示信息存入map并抛出一个异常给service。在service方法上开启事务&#xff0c;并将异常出实现数据回滚&#xff0…

vite使用vue3 v-for渲染图片时的写法

写法一 <template><divclass"demo-img"v-for"item in demoOption":key"item.code":style"background-image: url(${getImageUrl(../assets/imge/${item.img}.jpeg)})"></div> </template><script lang&qu…

2023网安最流行的10大工具(附安装包)

从事网络安全工作&#xff0c;手上自然离不开一些重要的网络安全工具。今天&#xff0c;分享10大网络安全工具。 一、Kali Linux Kali 是一个基于 Debian 的 Linux 发行版。它的目标就是为了简单&#xff1a;在一个实用的工具包里尽可能多的包含渗透和审计工具。Kali 实现了这…

Linux 之Python 定制篇-APT 软件管理和远程登录

Linux 之Python 定制篇-APT 软件管理和远程登录 apt 介绍 apt 是Advanced Packaging Tool 的简称&#xff0c;是一款安装包管理工具。在Ubuntu 下&#xff0c;我们可以使用apt 命令进行软件包的安装、删除、清理等&#xff0c;类似于Windows 中的软件管理工具。 unbuntu 软件…

【C++】深拷贝浅拷贝

前言&#xff1a;在 C 中&#xff0c;当一个对象通过赋值或拷贝即将成为另一个对象的副本时&#xff0c;会发生“浅拷贝”或“深拷贝”。 什么是浅拷贝&#xff1f; 浅拷贝是指两个对象共享同一个内存地址&#xff0c;即将源对象的数据成员的地址赋给了目标对象&#xff0c;当…

vue diff算法与虚拟dom知识整理(15) 终结篇,收尾新前到旧前全部不匹配情况

我们现在就只需要处理最后一种情况了 我们在 updateChildren.js 在while中 的if最后加个 else 当他们都没哟匹配到的情况 我们现在在updateChildren.js最上面 定义一个空对象 叫 keyMap 参考代码如下 let keyMap null;然后 在我们刚写的else中编写代码如下 //判断 如果…

Stable-Diffusion|入门怎么下载与使用civitai网站的模型(二)

C站&#xff1a;https://civitai.com/ 文章目录 1 样图2 实现2.1 下载主模型并放到正确文件夹中2.2 找到prompt2.3 生成2.4 Lora使用 3 一些有趣的项目3.1 胶片风格Lora3.2 [最近很火] 现实感很强的Majicmix-realistic 先贴几张笔者自己实验的图&#xff0c;模型来自&#xff1…

Libevent学习

一、Libevent概述 1、简介 Libevent 是一个用C语言编写的、轻量级的开源高性能事件通知库&#xff0c;主要有以下几个亮点&#xff1a;事件驱动&#xff08; event-driven&#xff09;&#xff0c;高性能;轻量级&#xff0c;专注于网络&#xff0c;不如 ACE 那么臃肿庞大&…

C++必背基础知识点总结

重点&#xff1a;不借助任何外部资料就能掌握&#xff0c;考试面试大概率涉及。 掌握&#xff1a;不借助任何外部资料就能掌握&#xff0c;考试面试有可能涉及。 熟悉&#xff1a;可以适当参考资料掌握&#xff0c;考试面试有可能涉及。 了解&#xff1a;可是参考资料掌握&…

iptables的四表五链

文章目录 1. Iptables的链2.Iptables的表3.数据包过滤的匹配流程3.1 规则表之间的顺序3.2 规则链之间的顺序3.3 规则链内部各条防火墙规则之间的顺序3.4如何应用 每个 规则表&#xff0c;其实就相当于一个内核空间的容器&#xff0c; 按照规则集的不同用途进行划分为默认的四…

w11+wsl+3060安装cuda等深度学习环境

把一切都重新又梳理学习了一遍&#xff0c;然后发现很多事情其实没必要弄 0. 显卡驱动、nvidia-smi、cuda、nvcc、cuDNN、pytorch、cudatoolkit与它们之间的关系 笔者本人鸟枪换炮了&#xff0c;还是wsl环境香&#xff0c;但是按照官方教程跑完后&#xff0c;遇到了bugRuntim…

RTMPose关键点检测实战——笔记3

文章目录 摘要安装MMPose安装虚拟环境安装pytorch安装MMCV安装其他的安装包下载 MMPose下载预训练模型权重文件和视频素材 安装MMDetection安装Pytorch安装MMCV安装其它工具包下载 MMDetection安装MMDetection下载预训练模型权重文件和视频素材 MMPose预训练模型预测命令行的方…

关于render: h => h(App)的解释

当我们第一次安装完脚手架&#xff0c;打开 的时候&#xff0c;我相信&#xff0c;一定有小伙伴和我一样&#xff0c;看到main.js里面的render: h > h(App),感觉懵懵的。 因为&#xff0c;在刚开始接触vue的时候&#xff0c;我们这里是这样写的&#xff1a; 而使用了脚手…