排序算法(初阶)【冒泡,插入,选择排序】

文章目录

  • 冒泡排序
    • 冒泡排序原理
    • 图解
    • 冒泡排序算法名称由来
    • 冒泡排序算法的时间复杂度
      • 最好的情况
      • 最坏的情况
    • 冒泡排序代码
    • 冒泡排序的稳定性
  • 选择排序
    • 选择排序的原理
    • 图解
    • 选择排序的时间复杂度
    • 选择排序的代码
      • 代码
    • 选择排序的稳定性
  • 插入排序
    • 插入排序原理
    • 图解
    • 插入排序的时间复杂度
      • 最好的情况
      • 最坏的情况
    • 插入排序的代码实现
    • 插入排序的稳定性

冒泡排序

冒泡排序原理

比较相邻的两个元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对,这被称为一趟冒泡排序

这样就可以把数组中要排序的数中的最大值放到最后,也相当于把一个元素排在了元素有序时它应处于的位置,它既然已经处于正确的位置就不需要在排这个元素了
所以下一趟冒泡排序就可以少排一个元素

针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
一一一一一一一一一一一一一一一一一一一一
一一一一一一一一一一一一一一一一一一一一

图解

在这里插入图片描述由上图,冒泡排序每一趟都会把要排序元素中最大的冒到最后一个

一一一一一一一一一一一一一一一一一一一一
一一一一一一一一一一一一一一一一一一一一

冒泡排序算法名称由来

这个算法的名字由来是因为越大(小)的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。

一一一一一一一一一一一一一一一一一一一一
一一一一一一一一一一一一一一一一一一一一

冒泡排序算法的时间复杂度

最好的情况

要排升序(降序)时,要排序的元素已经是升序(降序),此时冒泡排序只是扫描了一遍要排序的元素,发现没有发生交换,就结束排序。
此时时间复杂度为N-1

一一一一一一一一一一一一一一一一一一一一
一一一一一一一一一一一一一一一一一一一一

最坏的情况

要排升序(降序)时,要列的元素是降序(升序)。
此时冒泡排序要排N-1趟
要排的元素个数从第一趟到最后一趟交换的次数为N-1,N-2,N-3…1
所以时间复杂度为1+2+3+…+N-1=(N^2-N)/2

所以冒泡排序平均的时间复杂度为O(N^2)

一一一一一一一一一一一一一一一一一一一一
一一一一一一一一一一一一一一一一一一一一

冒泡排序代码

//冒泡排序
void bubbleSort(int a[], int n)
{
	int i = 0;
	int j = 0;
	int flag = 0;
	//总共需要n趟冒泡排序
	for (i = 0; i < n; i++)
	{
		//重置flag的值
		flag = 0;

		//一趟冒泡排序,排出一个最大值
		for (j = 0; j < n - i - 1; j++)
		{
			if (a[j] > a[j + 1])
			{
			//交换
				int tmp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = tmp;
				
			//只要一趟冒泡排序发生了交换,就还没排序完成
				flag = 1;
			}
		}
		//如果一趟冒泡排序之后,flag还是0,
		//就说明没有交换,已经有序
		if (flag == 0)
			break;
	}
}

一一一一一一一一一一一一一一一一一一一一
一一一一一一一一一一一一一一一一一一一一

冒泡排序的稳定性

冒泡排序就是把小的元素往前调或者把大的元素往后调。
比较是相邻的两个元素比较,交换也发生在这两个元素之间。
所以,如果两个元素相等,是不会再交换的;

如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变

所以冒泡排序是一种稳定排序算法。

一一一一一一一一一一一一一一一一一一一一
一一一一一一一一一一一一一一一一一一一一

选择排序

选择排序的原理

选择排序是一种简单直观的排序算法。它的工作原理是:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。

一一一一一一一一一一一一一一一一一一一一
一一一一一一一一一一一一一一一一一一一一

图解

请添加图片描述由上图,选择排序每一趟都选择一个无序数列中最小的放在有序数列末尾,直到无序序列的元素个数为1。

一一一一一一一一一一一一一一一一一一一一
一一一一一一一一一一一一一一一一一一一一

选择排序的时间复杂度

选择排序的交换操作介于 0 和 (n - 1)次之间。选择排序的比较操作为 n (n - 1) / 2 次之间。选择排序的赋值操作介于 0 和 3 (n - 1) 次之间。比较次数O(n^2),比较次数与关键字的初始状态无关,总的比较次数N=(n-1)+(n-2)+…+1=n*(n-1)/2。交换次数O(n),最好情况是,已经有序,交换0次;最坏情况交换n-1次,逆序交换n/2次。

所以选择排序的平均时间复杂度为O(N^2)

一一一一一一一一一一一一一一一一一一一一
一一一一一一一一一一一一一一一一一一一一

选择排序的代码

代码

//选择排序
void SelectSort(int a[], int n)
{
	//count表示有序序列末尾的下标
	int count= 0;
	int i = 0;
	//min为最小值的下标
	int min = 0;
	while(count<n)
	{
		//每一趟选择排序都从有序数列末尾开始找最小值
		min = count;
		for (i = count; i<n;i++)
		{
			if (a[min] > a[i])
				min = i;
		}
		//Swap为交换函数
		Swap(&a[count], &a[min]);
		//每一趟选择排序之后有序数列末尾下标加一
		count++;
	}
}

一一一一一一一一一一一一一一一一一一一一
一一一一一一一一一一一一一一一一一一一一

选择排序的稳定性

在一趟选择排序中,如果一个元素比当前元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。
例如序列2,2,2,1,3
第一趟选择排序会把1与第一个2交换,导致原本应在前面的2跑到后面去了

所以选择排序是不稳定的

一一一一一一一一一一一一一一一一一一一一
一一一一一一一一一一一一一一一一一一一一

插入排序

插入排序原理

插入排序是指在待排序的元素中,假设前面n-1(其中n>=2)个数已经是排好顺序的,现将第n个数插到前面已经排好的序列中,然后找到合适自己的位置,使得插入第n个数的这个序列也是排好顺序的。按照此法对所有元素进行插入,直到整个序列排为有序的过程,称为插入排序。

插入排序的工作方式像许多人排序一手扑克牌。开始时,我们的左手为空并且桌子上的牌面向下。然后,我们每次从桌子上拿走一张牌并将它插入左手中正确的位置。为了找到一张牌的正确位置,我们从右到左将它与已在手中的每张牌进行比较。拿在左手上的牌总是排序好的,原来这些牌是桌子上牌堆中顶部的牌

一一一一一一一一一一一一一一一一一一一一
一一一一一一一一一一一一一一一一一一一一

图解

请添加图片描述
一一一一一一一一一一一一一一一一一一一一
一一一一一一一一一一一一一一一一一一一一

插入排序的时间复杂度

最好的情况

要排升序(降序)时,要排序的元素已经是升序(降序)
此时只需当前数跟前一个数比较一下就可以了,这时一共需要比较N- 1次

此时时间复杂度为O(N)

一一一一一一一一一一一一一一一一一一一一
一一一一一一一一一一一一一一一一一一一一

最坏的情况

要排升序(降序)时,要列的元素是降序(升序)。
此时总次数记为:1+2+3+…+N-1,所以,插入排序
最坏情况下的时间复杂度为O(N^2)

所以插入排序的平均时间复杂度为O(N^2)

一一一一一一一一一一一一一一一一一一一一
一一一一一一一一一一一一一一一一一一一一

插入排序的代码实现

//插入排序
void lnsertionSort(int a[], int n)
{
	//end表示有序序列最末尾的元素的下标
	int end = 0;
	//tmp表示无序序列的第一个元素的下标
	int tmp = 0;
	//i控制插入排序的趟数
	int i = 0;
	for (i = 0;i < n - 1; i++)
	{
		end = i;
		tmp = a[end + 1];
		while (end >= 0)//end最小是0
		{
			if (a[end] > tmp)
			{
				//如果前一个大于后一个,就让前一个向后移一位
				//给后一个可插入的空隙
				a[end + 1] = a[end];
				end--;
			}
			else
			{
				//因为是从已经有序的序列的末尾向前插入
				//所以前一个之前的元素都比它小,所以不用再比较,直接结束循环
				break;
			}		
		}
		a[end + 1] = tmp;
	}
}

一一一一一一一一一一一一一一一一一一一一
一一一一一一一一一一一一一一一一一一一一

插入排序的稳定性

如果待排序的序列中存在两个或两个以上具有相同关键词的数据,排序后这些数据的相对次序保持不变,即它们的位置保持不变

所以插入排序是稳定的

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用 Neo4j 和 LangChain 集成非结构化知识图增强 QA

目前基于大模型的信息检索有两种方法&#xff0c;一种是基于微调的方法&#xff0c;一种是基于 RAG 的方法。 信息检索和知识提取是一个不断发展的领域&#xff0c;随着大型语言模型&#xff08;LLM&#xff09;和知识图的出现&#xff0c;这一领域发生了显着的变化&#xff0…

2.4 网络层01

2.4 网络层01 2.4.1 网络层概述 网络层的主要任务是实现网络互连&#xff0c;进而实现数据包在各网络之间的传输。 异构网络内部的计算机要想实现通信是不需要实现网络互联的&#xff0c;异构网络之间要想实现通信就必须实现网络互连。 路由器工作在五层协议体系结构的网络…

HCIA的路由协议

动态路由协议/静态路由协议 静态路由协议和动态路由协议的区别&#xff1a; 静态路由协议的缺点&#xff1a; 配置繁琐 针对拓扑的变化不能够自动收敛 只适用于小型网络 静态路由协议优点&#xff1a; 占用资源少 安全 稳定 动态路由协议的优点&#xff1a; 配置简单 针对拓…

风丘科技为您提供完整的ADAS测试方案

一 方案概述 随着5G通讯与互联网的快速发展&#xff0c;智能汽车和ADAS辅助系统的研究与发展在世界范围内也在如火如荼地进行。风丘科技紧跟时代脚步&#xff0c;经多年积累沉淀&#xff0c;携手整车厂与高校共同研发打造出了一套完整且适用于国内ADAS测试的系统方案。 | ADAS…

YOLOv5改进 | 二次创新篇 | 升级版本Dyhead检测头替换DCNv3 实现完美升级(全网独家首发)

一、本文介绍 本文给大家带来的改进机制是在DynamicHead上替换DCNv3模块,其中DynamicHead的核心为DCNv2,但是今年新更新了DCNv3其作为v2的升级版效果肯定是更好的,所以我将其中的核心机制替换为DCNv3给Dyhead相当于做了一个升级,效果也比之前的普通版本要好,这个机制我认…

从0开始python学习-49.pytest之日志封装和allure封装

目录 日志封装 1. 在pytest.ini中配置日志的格式 2. 生成日志对象--在请求封装中写 3. 把日志写入文件--在请求封装中写 allure封装 1. 在yaml用例中写入需要的模块、接口等内容 2. 在测试用例封装的函数中通过allure.dynamic的方法写入需要的数据 日志封装 1. 在pytest.…

知识付费saas租户平台:发掘企业知识宝藏,开启专属知识付费新时代

产品服务 线上线下课程传播 线上线下活动管理 项目撮合交易 找商机找合作 一对一线下交流 企业文化宣传 企业产品销售 明理信息科技知识付费saas租户平台 更多服务 实时行业资讯 动态学习交流 分销代理推广 独立知识店铺 覆盖全行业 个人IP打造 独立小程序 私…

第十届教育和培训技术国际会议 (ICETT 2024)即将召开!

2024年第十届教育和培训技术国际会议&#xff08;ICETT 2024&#xff09;将于2024年4月11-13日在中国澳门召开&#xff0c;由澳门理工大学主办&#xff0c;香港教育大学协办。作为一项历史悠久的年度盛会&#xff0c;ICETT已在新加坡、芬兰、韩国等地成功举办了九届。本次会议依…

3DGS 其一:3D Gaussian Splatting for Real-Time Radiance Field Rendering

3DGS 其一&#xff1a;3D Gaussian Splatting for Real-Time Radiance Field Rendering 1. 预备知识1.1 球谐函数1.2 Splatting1.3 α \alpha α blending1.4 多维高斯的协方差矩阵1.4.1 高斯与椭球体的关系1.4.2 世界坐标系下的三维高斯到二维像素平面投影过程 2. 3D Gaussia…

PICO Developer Center 创建和调试 ADB 命令

PICO 开发者中心概览 ADB 是一个轻量级的 Android 调试桥(Android Debug Bridge&#xff0c;简称 ADB)&#xff0c;用于与 Android 设备进行通信和调试。ADB提供了许多有用的功能&#xff0c;使开发人员能够轻松地管理和调试设备上的应用程序。 你可以使用 PDC 工具来调试系统…

按键检测|中断检测

一.按键检测 1.硬件原理 当未按下按键时&#xff0c;GPIO_5为低电平&#xff0c;按下按键GPIO_5变为高电平。 根据引脚编号找到引脚名称 根据引脚名称找到引脚编号 裸机程序控制外设 特点&#xff1a;读数据手册、设寄存器值 找出外设有哪些相关寄存器找出外设相关寄存器如何…

Kafka-消费者-Consumer Group Rebalance设计

在同一个Consumer Group中&#xff0c;同一个Topic的不同分区会分配给不同的消费者进行消费&#xff0c;那么为消费者分配分区的操作是在Kafka服务端完成的吗?分区是如何进行分配呢?下面来分析Rebalance操作的原理。 方案一 Kafka最开始的解决方案是通过ZooKeeper的Watcher…

Nginx 简介

1、概念介绍 Nginx ("engine x") 是一个轻量级、高性能的 WEB 服务器软件和反向代理服务器。 Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的&#xff0c;第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。其将源代码以类 BSD 许可证的形式发…

手机崩溃日志的查找与分析

手机崩溃日志的查找与分析 摘要 本文介绍了一款名为克魔助手的iOS应用日志查看工具&#xff0c;该工具可以方便地查看iPhone设备上应用和系统运行时的实时日志和崩溃日志。同时还提供了崩溃日志的分析查看模块&#xff0c;可以对苹果崩溃日志进行符号化、格式化和分析&#x…

【Spring实战】30 创建自己的 Spring Boot HelloWorld Starter

文章目录 1. 定义2. 创建3. 依赖4. 编写自动配置类5. 编写 HelloWorldService 类6. 编写 Starter 配置文件7. 打包并发布到本地仓库7. 引入 HelloWorld Starter8. 使用 HelloWorld结语 Spring Boot Starter 是一项强大的功能&#xff0c;可以帮助我们轻松集成和配置各种常用组件…

微信小程序中的两种页面跳转方式

方式一(声明式导航): 利用<navigator></navigator> url:要跳转页面的地址 open-type:要打开的页面的类型 &#xff08;不在底部导航中添加的为非导航页面&#xff0c;在的为导航页面&#xff09; 非导航页面跳转过去后左上角会出现返回箭头&#xff0c;导航页面…

KNN算法原理及应用

理解KNN 算法原理 KNN是监督学习分类算法&#xff0c;主要解决现实生活中分类问题。 根据目标的不同将监督学习任务分为了分类学习及回归预测问题。 监督学习任务的基本流程和架构&#xff1a; &#xff08;1&#xff09;首先准备数据&#xff0c;可以是视频、音频、文本、…

appium之联动pycharm

前置条件&#xff1a; 1.java环境安装好了 2.android-sdk安装好&#xff08;uiautomatorviewer 也可以把这个启动起来&#xff09; 3.appium安装好 4.adb devices查看下设备是否连接 pycharm入门代码--固定写法 from appium import webdriver# 定义字典变量 desired_caps …

机器学习笔记——机器学习的分类

1 机器学习是啥 机器学习是人工智能的一个分支&#xff0c;它是一门研究机器获取新知识和新技能&#xff0c;并识别现有知识的学问。 机器学习已广泛应用于数据挖掘、计算机视觉、自然语言处理、生物特征识别、搜索引擎、医学诊断、检测信用卡欺诈、证券市场分析、DNA 序列测…

Luckysheet类似excel的在线表格(vue)

参考文档&#xff1a;快速上手 | Luckysheet文档 一、引入 在vue项目的public文件夹下的index.html的<head>标签里面引入 <link relstylesheet hrefhttps://cdn.jsdelivr.net/npm/luckysheetlatest/dist/plugins/css/pluginsCss.css /><link relstylesheet hre…