选择排序、冒泡排序----C语言数据结构

目录

    • 引言
  • 1.选择排序的实现
  • 1.1选择排序的时间复杂度
  • 2.冒泡排序的实现
  • 2.1冒泡排序的时间复杂度分析及优缺

引言

选择排序(Selection Sort)是一种简单直观的排序算法,它的基本思想是每次从未排序的元素中选择最小(或最大)的元素,然后将其放置在已排序部分的末尾。这个过程不断重复,直到所有元素都被排序完成。

选择排序虽然在时间复杂度上不如一些高级的排序算法,但由于其简单直观的实现方式,以及在某些特定情况下的一些优势:

  1. 小型数据集:选择排序在处理小规模数据集时可能比较适用。由于其基本操作是选择最小元素并交换,对于较小规模的数据集,选择排序可能不会带来很大的性能损失,并且实现较为简单。
  2. 内存有限的环境:
    由于选择排序是一种原地排序算法,它不需要额外的存储空间,仅使用常数级别的额外空间。在内存有限的环境下,选择排序可能是一个可行的选择,因为它不会占用太多内存。

1.选择排序的实现

基本思想: 每一次从待排序的数据元素中选出最小(或者最大的)的一个元素,置于最前端也就是序列的起始位置,使最前端的数据元素是有序的,直到全部待排序的数据元素全都排列完全

思路:

  1. 在元素集合array[i]–array[n-1]中选择关键码最大(小)的数据元素
  2. 若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换
  3. 在剩余的array[i]–array[n-2](array[i+1]–array[n-1])集合中,继续此操作
    插入排序

初始版

void Swap(int* a, int* b)
{
	int c = *a;
	*a = *b;
	*b = c;
}

void SelectSort(int* a, int n)
{
	for (int j = 0;j < n;j++)
	{
	//注意这里min记录的是下标而不是值,原因是记录值,无法实现交换
		int begin = j, min = begin;
		for (int i = j;i < n;i++)
		{
			if (a[i] <= a[min])
			{
				min = i;
			}
		}
		Swap(&a[begin], &a[min]);
	}
}

优化版
在实践中我们其实是可以再一趟循环中,同时交换最大值和最小值,也就是将最小值放到最前面,将最大值放到最后面,来提升效率

void SelectSort(int* a, int n)
{
	int begin = 0,end = n;
	while (begin<end)
	{
		//记录一趟循环的最大最小值
		int min = begin, max = begin;
		for (int i = begin + 1;i < end;i++)
		{
			if (a[i] <= a[min])
				min = i;
			if (a[i] > a[max])
				max = i;
		}
		Swap(&a[begin], &a[min]);
		//防止最大值为begin而被交换
		if (max == begin)
		{
			max = min;
		}
		Swap(&a[end - 1], &a[max]);
		begin++;
		end--;
	}
}

1.1选择排序的时间复杂度

时间复杂度是O(n^2)

  1. 最好情况时间复杂度:
    在最好的情况下,即输入数组已经是有序的状态,选择排序每次只需要比较一次元素就能确定最小值,然后进行一次交换。因此,最好情况时间复杂度为 O(n^2)。

  2. 最坏情况时间复杂度:
    在最坏的情况下,即输入数组是逆序的状态,选择排序每次都需要比较未排序部分的所有元素,找到最小值,然后进行交换。对于长度为 n 的数组,第一次需要比较 n 次,第二次需要比较 n-1 次,以此类推,总的比较次数是 n + (n-1) + (n-2) + … + 1,可以用等差数列求和公式求解,最坏情况时间复杂度为 O(n^2)。

  3. 平均情况时间复杂度:
    在平均情况下,选择排序的性能也是 O(n^ 2)。这是因为无论初始数组的顺序如何,每次选择都需要进行一次完整的未排序部分的遍历,找到最小值进行交换。平均情况下,比较次数和交换次数都是 O(n^2)。

  1. 简单直观: 选择排序是一种非常简单直观的排序算法,易于理解和实现。这使得它成为学习排序算法的良好入门例子。

  2. 原地排序: 选择排序是一种原地排序算法,只需要常数级别的额外空间。

  3. 不受输入数据分布影响:
    与某些排序算法(例如快速排序)不同,选择排序的性能不会受输入数据的分布情况的影响。它在任何情况下都需要相同数量的比较和交换操作。

  1. 低效率: 选择排序的时间复杂度为
    O(n^2),无论输入数据的分布如何,它都需要进行相同数量的比较和交换操作。在大规模数据集上,性能相对较差。

  2. 不稳定性: 选择排序是一种不稳定的排序算法,相等元素的相对顺序在排序后可能发生改变。

  3. 固定元素位置:选择排序每次都会选择最小的元素放置到正确的位置,这可能导致一些已经有序的元素在排序过程中仍然会发生交换,增加了不必要的操作。

  4. 不适用于部分有序数组: 对于部分有序的数组,选择排序的性能也较差,因为它在每一轮都会进行完整的比较和交换操作。

2.冒泡排序的实现

冒泡排序是比较基础的排序算法之一,其思想是相邻的元素两两比较,较大的数下沉,较小的数冒起来,这样一趟比较下来,最大(小)值就会排列在一端。整个过程如同气泡冒起,因此被称作冒泡排序。
  冒泡排序的步骤是比较固定的:

  1. 俩俩相邻元素比较,大的往后沉 (也就是交换),小的往前冒[单趟,内层循环]
  2. 按待排序数组的元素,依次重复遍历(外层循环),直到遍历整个数组

在这里插入图片描述

void Swap(int* a, int* b)
{
	int c = *a;
	*a = *b;
	*b = c;
}


//冒泡排序,把最大的排最后,排除最大的后的数组再遍历排最大
void BubbleSort(int* a, int n)
{	for(int j=0;j<n-1;j++)
	{
		for (int i = 0;i <n-j-1;i++)
		{
			if (a[i] > a[i + 1])
			{
				Swap(&a[i], &a[i + 1]);
			}
		}
	}
}

2.1冒泡排序的时间复杂度分析及优缺

时间复杂度是O(n^2)

最优:待排序数组是有序的,此时,内层的循环不用交换,只有外层循环遍历,所以时间复杂度为O(n^2)

最差:待排序数组是逆序的,此时,内层的循环需要完全遍历,交换。最坏情况时间复杂度为 O(n^2)。

平均:在平均情况下,冒泡排序的性能也是 O(n^2)。虽然在最好情况下只需要一次遍历,但平均情况下需要进行多次遍历,每次遍历的比较和交换次数都会影响总体的时间复杂度。

  1. 简单易理解: 冒泡排序是一种直观、容易理解的排序算法,适用于初学者学习排序算法的入门。
  2. 稳定性: 冒泡排序是一种稳定的排序算法,相等元素的相对顺序在排序后不会改变。
  3. 原地排序: 冒泡排序是一种原地排序算法,只需要常数级别的额外空间。

缺:

  1. 低效率: 冒泡排序的平均和最坏情况时间复杂度均为 O(n^2),性能相对较差,尤其在大规模数据集上。

  2. 不适合大规模数据: 由于其较高的时间复杂度,冒泡排序在处理大规模数据时效率较低,不如一些高级排序算法。

  3. 交换次数较多: 冒泡排序的主要操作是相邻元素的比较和交换,尤其在逆序的情况下,交换次数较多。

  4. 不适用于部分有序数组: 对于部分有序的数组,冒泡排序的性能也较差,因为它仍然需要进行大量的比较和交换操作。

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

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

相关文章

VitePress-08-文档中代码组的使用

什么是代码组 代码组 : 就是代码块的集合。一个代码组中可以包含多个代码块。 效果 &#xff1a; 用页签的形式将不同的代码块分开展示。 代码组的语法格式 代码组的语法格式较为固定&#xff0c;如下 &#xff1a; ::: code-group代码块1的类型 [代码块1展示的页签名称]代码块…

全新 鸿蒙系统

一&#xff0c; 开发框架 基础 二&#xff0c; 官网地址 文档开发&#xff1a;华为HarmonyOS智能终端操作系统官网 | 应用设备分布式开发者生态 三&#xff0c;基础了解 鸿蒙系统是基于 js 和 ts 衍生出来的一个东西 要学 arkts 就要学习 js 和 ts 语法 四&#xff0c…

Avalonia学习(二十二)-数据库操作端

开始项目式的例子&#xff0c;但是不方便给大家贴代码了。 内容很多&#xff0c;只能演示一个界面&#xff0c;例子上传。 我不擅长界面美化和配色&#xff0c;有兴趣的可以继续完善&#xff0c;当前实现mysql。 最近所有样例的地址&#xff1a; GitHub - jinyuttt/Avalonia…

基于条纹投影的三维形貌与形变测量技术研究

▒▒本文目录▒▒ 一、 引言二、基于条纹投影轮廓术的形变测量实验2.1 实验光路2.2 实验结果 三、参考文献四、结论五、软硬件系统开发六、交流与合作 一、 引言 作为一种典型的三维形貌重建方法&#xff0c;条纹投影轮廓测量术&#xff08;Fringe Projection Profilometry&am…

java入门、环境配置及其特点介绍

目录 一、java语言的重要特点 二、java开发工具包&#xff08;JDK&#xff09;及其环境配置 三、java入门代码 四、Java运行机制 五、java学习方法 一、java语言的重要特点 java是面向对象的Java是健壮性的。Java具有强类型机制、异常处理、垃圾的自动收集等特点java语言是跨…

炼丹师必备平台,云上训练无压力—GpuMall智算云

说回作为一个“炼丹师”在选择炼丹平台的核心需求&#xff1a;【数据传输速率快慢】or【机器租用价格性价比】or【可租用机器类型多少】or【镜像版本选择多样性】or【机器稳定性】等等 是不是以上任何一个条件&#xff0c;都可能会影响你对平台的选择呢&#xff1f;纵观市面上…

python coding with ChatGPT 打卡第16天| 二叉树:完全二叉树、平衡二叉树、二叉树的所有路径、左叶子之和

相关推荐 python coding with ChatGPT 打卡第12天| 二叉树&#xff1a;理论基础 python coding with ChatGPT 打卡第13天| 二叉树的深度优先遍历 python coding with ChatGPT 打卡第14天| 二叉树的广度优先遍历 python coding with ChatGPT 打卡第15天| 二叉树&#xff1a;翻转…

曲线拟合、多项式拟合、最小二乘法

最近在做自车轨迹预测的工作&#xff0c;遇到 曲线拟合、多项式拟合、最小二乘法这些概念有点不清晰&#xff0c; 做一些概念区别的总结&#xff1a; 曲线拟合用于查找一系列数据点的“最佳拟合”线或曲线。 大多数情况下&#xff0c;曲线拟合将产生一个函数&#xff0c;可用于…

【数据结构与算法】(7)基础数据结构之双端队列的链表实现、环形数组实现示例讲解

目录 2.6 双端队列1) 概述2) 链表实现3) 数组实现习题E01. 二叉树 Z 字层序遍历-Leetcode 103 2.6 双端队列 1) 概述 双端队列、队列、栈对比 定义特点队列一端删除&#xff08;头&#xff09;另一端添加&#xff08;尾&#xff09;First In First Out栈一端删除和添加&…

网工内推 | 金融业网络安全岗,最高40K*15薪,CISP认证优先

01 国泰产险 招聘岗位&#xff1a;资深信息安全工程师 职责描述&#xff1a; 1、负责公司云平台业务系统的安全规划设计&#xff0c;协助业务系统制定安全解决方案&#xff1b; 2、负责建立公司信息安全标准&#xff0c;制定平台安全策略&#xff0c;安全加固&#xff0c;防范…

数据可视化 pycharts实现中国各省市地图数据可视化

自用版 数据格式如下&#xff1a; 运行效果如下&#xff1a; import pandas as pd from pyecharts.charts import Map, TreeMap, Timeline, Page, WordCloud from pyecharts import options as opts from pyecharts.commons.utils import JsCode from pyecharts.globals im…

js逆向-某验3代滑块验证码分析

声明 本文仅供学习参考&#xff0c;如有侵权可私信本人删除&#xff0c;请勿用于其他途径&#xff0c;违者后果自负&#xff01; 如果觉得文章对你有所帮助&#xff0c;可以给博主点击关注和收藏哦&#xff01; 插句个人内容&#xff1a;本人最近正在找工作&#xff0c;工作城…

alibabacloud学习笔记05(小滴课堂)

高并发下的微服务存在的问题 高并发下的微服务容错方案 介绍什么是分布式系统的流量防卫兵Sentinel 微服务引入Sentinel和控制台搭建 每个服务都加上这个依赖。 启动方式&#xff1a; 讲解AliababCloud微服务整合Sentinel限流配置实操 我们在order和video模块都加上。 分别启动…

第三百零六回

文章目录 1. 概念介绍2. 思路与方法2.1 实现思路2.2 实现方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"分享三个使用TextField的细节"沉浸式状态样相关的内容&#xff0c;本章回中将介绍如何创建单例模式.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1.…

回归预测 | Matlab实现POA-CNN-LSTM-Attention鹈鹕算法优化卷积长短期记忆网络注意力多变量回归预测(SE注意力机制)

回归预测 | Matlab实现POA-CNN-LSTM-Attention鹈鹕算法优化卷积长短期记忆网络注意力多变量回归预测&#xff08;SE注意力机制&#xff09; 目录 回归预测 | Matlab实现POA-CNN-LSTM-Attention鹈鹕算法优化卷积长短期记忆网络注意力多变量回归预测&#xff08;SE注意力机制&…

超时引发的牛角尖二(hystrix中的超时)

至今我都清楚记得自己负责的系统请求云上关联系统时所报的异常信息。为了解决这个异常&#xff0c;我坚持让这个关联系统的负责人查看&#xff0c;并且毫不顾忌他的嘲讽和鄙视&#xff0c;甚至无视他烦躁的情绪。不过我还是高估了自己的脸皮&#xff0c;最终在其恶狠狠地抛下“…

智能决策的艺术:探索商业分析的最佳工具和方法

文章目录 一、引言二、商业分析思维概述三、数据分析在商业实践中的应用四、如何培养商业分析思维与实践能力五、结论《商业分析思维与实践&#xff1a;用数据分析解决商业问题》亮点内容简介作者简介目录获取方式 一、引言 随着大数据时代的来临&#xff0c;商业分析思维与实…

前端小案例——滚动文本区域(HTML+CSS, 附源码)

一、前言 实现功能: 这个案例实现了一个具有滚动功能的文本区域&#xff0c;用于显示长文本内容&#xff0c;并且可以通过滚动条来查看完整的文本内容。 实现逻辑&#xff1a; 内容布局&#xff1a;在<body>中&#xff0c;使用<div>容器创建了一个类名为listen_t…

vue3 之 组合式API—watch函数

watch函数 作用&#xff1a;侦听一个或者多个数据的变化&#xff0c;数据变化时执行回调函数 两个额外参数&#xff1a; 1.immediate&#xff08;立即执行&#xff09;2.deep&#xff08;深度侦听&#xff09; 场景&#xff1a;比如选择不同的内容请求后端不同数据时 如下图 …

【算法与数据结构】300、674、LeetCode最长递增子序列 最长连续递增序列

文章目录 一、300、最长递增子序列二、674、最长连续递增序列三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、300、最长递增子序列 思路分析&#xff1a; 第一步&#xff0c;动态数组的含义。 d p [ i ] dp[i] dp[i…