【数据结构】排序3——交换排序(冒泡排序、快速排序)

news2024/11/27 21:05:55

文章目录

  • 交换排序
    • 冒泡排序
      • 冒泡排序算法
      • 算法分析
    • 快速排序
      • 改进后的快速排序算法
      • 算法分析


交换排序

【基本思想】
两两比较,如果发生逆序则交换,直到所有记录都排好序为止。

常见的交换排序方法:
冒泡排序T(n)=O(n2)
快速排序T(n)=O( nlog2n)

冒泡排序

——基于简单交换思想

【基本思想】
每趟不断将记录两两比较,并按“前小后大”规则交换。
第一个数和第二个数比较,若第一个数大于第二个数,则交换位置,否则,位置不变;
完成之后第二个数和第三个数比较,若第二个数大于第三个数,则交换位置,否则位置不变;
完成之后第三个数和第四个数比较,……
直到比较到最后一个数。

例:
在这里插入图片描述
21<25,位置不变
25<49,位置不变
49>25,互换位置
……
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
总结:
n个数据记录,总共需要比较n-1趟。
第m趟需要比较n-m次。

冒泡排序算法

void bubble_sort(SqList &L){
	int m,i,j;
	RedType x;//交换时临时存储
	for(m=1;m<=n-1;m++){//总共需要比较m趟
		for(j=1;j<=n-m;j++){
			if(L.r[j].key>L.r[j+1].key)//发生逆序
				x=L.r[j];//交换
				L.r[j]=L.r[j+1];
				L.r[j+1]=x;
		}
	}
}

优点:
每趟结束时,不仅能挤出一个最大值到最后面位置,还能同时部方理顺其他元素。

提高排序算法效率:
一旦某一趟比较时不出现记录交换,说明已排好序了,就可以结束本算法。

void bubble_sort(SqList &L){
	int m,i,j,flag=1;//flag作为是否有交换的标记,有交换flag=1,没交换flag=0
	for(m=1;m<=n-1&&flag==1;m++){
		flag=0;
		for(j=1;j<=m;j++){
			if(L.r[j].key>L.r[j+1].key)//发生逆序
				flag=1;
				x=L.r[j];//交换
				L.r[j]=L.r[j+1];
				L.r[j+1]=x;
		}
	}
}

算法分析

时间复杂度:
平均时间复杂度为O(n2)
最好时间复杂度(正序)是O(n)
最坏时间复杂度(逆序)为O(n2)

空间复杂度:
算法中增加一个辅助空间temp
空间复杂度S(n)=O(1)

稳定性:
冒泡排序是一种稳定的排序方法。

快速排序

——改进的交换排序

pivot:枢轴、中心点

【基本思想】
① 任取一个元素为中心(中间数),通常是取第一个元素(枢轴),中间数可以是第一个数、最后一个数、最中间一个数、任选个数等;
② 所有比它小的元素一律前放,比它大的元素一律后放;(小的从前往后放,大的从后往前放)
③ 形成左右两个子表;
④ 对各子表重新选择中心元素并依此规则调整;(递归思想)
⑤ 直到每个子表的元素只剩一个,就达到整个序列有序。

优点:简单;
缺点:花费空间。

改进:
① 每一趟的子表的形成是采用从两头向中间交替式逼近法;
② 由于每趟中对各子表的操作都相似,可采用递归算法。
在这里插入图片描述

把第一次比较结束后的表以49为中心分成左右两个子表,对各子表重新选择中心元素并依此规则调整,这里左边选择了27作为中心元素,右边选择了76作为中心元素。

在这里插入图片描述

【基本步骤】
① 设下标1号元素作中间数(界点)pivotkey放置到0号下标位置,low指向第一个空,high指向末尾下标为L.length的位置。
② 由于low指向空,所以从high开始比较:
若high<pivotkey,则high的元素放置到low位置,且low的位置往后移一个位置low+1;
若high>pivotkey,则high的元素位置不变,high的位置也不变;
若high=pivotkey,则high的元素位置不变,high的位置也不变。
③ 由于high指向空,所以从low开始比较:
若low>pivotkey,则low的元素放置到high位置,且high的位置往后移一个位置high-1;
若low<pivotkey,则low的元素位置不变,low的位置也不变;
若low=pivotkey,则low的元素位置不变,low的位置也不变。
④ 直到low=high,把界点pivotkey移到low和high的位置,停止这趟比较。
⑤ 把第一次比较结束后的表以界点pivotkey为中心分成左右两个子表。
④ 对各子表重新选择中心元素并依此规则调整。(递归思想)
⑤ 直到每个子表的元素只剩一个,就达到整个序列有序。

改进后的快速排序算法

//主函数
void main(){
	QSort(L,1,L.length);//对顺序表L进行排序,需要排序的数据范围从位置1到位置L.length
}

void Partition(SqList &L,int low,int high){
	L.r[0]=L.r[low];//把中间数放到0号空位置
	pivotkey=L.r[low].key;
	while(low<high){//直到low=high,循环结束
		while(low<high&&L.r[high].key>=pivotkey)
			--high;
		L.r[low]=L.r[high];
		while(low<high&&L.r[low].key<=pivotkey)
			++low;
		L.r[high]=L.r[low];
	}
	L.r[low]=L.r[0];//此时low的位置和high的位置是一样的,是一个空位置
	return low;
}//时间复杂度:O(n)

void QSort(SqList &L,int low,int high){//对顺序表L进行排序,需要排序的数据范围从位置low到位置L.length
	if(low<high){
		pivotloc==Partition(L,low,high);
		//将L.r[low]到L.r[high]一分为二,pivotloc为枢轴元素排好序的位置
		QSort(L,low,pivotloc-1);//对低字表递归排序
		QSort(L,pivotloc+1,high);//对高字表递归排序
	}	
}//时间复杂度:O(log^2^n)

算法分析

时间复杂度:
可以证明,平均计算时间是O(nlog2n)。
Qsort( ):O(log2n)
Partition( ):O(n)
实验结果表明:就平均计算时间而言,快速排序是我们所讨论的所有内排序方法中最好的一个。

空间复杂度:
快速排序不是原地排序
由于程序中使用了递归,需要递归调用栈的支持,而栈的长度取决于递归调用的深度。(即使不用递归, 也需要用用户栈)
在平均情况下:需要O(logn)的栈空间
最坏情况下:栈空间可达O(n)。

稳定性:
快速排序是一种不稳定的排序方法。
例如: 49, 38, 49*, 20, 97, 76
一次划分后: 20, 38, 49*, 49, 97, 76
49和49*位置互换,所有不稳定

划分元素的选取是影响时间性能的关键。
快速排序不适于对原本有序或基本有序的记录序列进行排序,输入数据次序越乱,所选划分元素值的随机性越好,排序速度越快,快速排序不是自然排序方法


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

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

相关文章

SpringSecurity Oauth2实战 - 06 获取用户登录信息并存储到本地线程

文章目录1. 获取用户登录信息1. 用户信息共享的ThreadLocal类 UserInfoShareHolder2. 写一个拦截器 UserInfoInterceptor3. 配置拦截器 CommonWebMvcAutoConfiguration2. 源码分析1. 认证用户通过access_token访问受限资源2. 进入过滤器 OAuth2AuthenticationProcessingFilter#…

源码分析:Transport 开发

有关 transport 相关队列的调用过程: 【T ransportService 】 TransportService.java 的所有接口由 DefaultTransportService.java 实现,里面包含四种接口: (1)发送到 ruleEngine 发送 TbProtoQueueMsg<ToRuleEngineMsg> 消息。 由 DefaultTbRuleEngineConsumerServic…

【攻破css系列——附加篇】vscode自动格式化

文章目录1. 快速格式化1.1 格式化的定义1.2 vscode的格式化组合键2. 自动格式化2.1 定义2.2 设置自动格式化的步骤1. 快速格式化 1.1 格式化的定义 格式化会让我们的代码正确缩进&#xff0c;同级标签的缩进空格一致&#xff0c;最后使我们代码更好看且易懂。 没有格式化我们…

Nginx学习

Nginx学习 nginx的基本概念 nginx是什么&#xff1f;做什么事情&#xff1f; Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器&#xff0c;特点是占用内存少&#xff0c;并发能力强&#xff0c;事实上nginx的并发能力确实在同类型的网页服务器中表现较好。nginx专为…

gcc编程4步编译、调试c程序实操详解(Linux系统编程)

gcc编译可以执行程序4步骤:预处理、编译、汇编、链接 一、知识储备&#xff08;想看实战往下翻&#xff09; 在linux程序种&#xff0c;c程序需要用gcc进行编译&#xff0c;链接用ld程序&#xff0c;ggc编译完成后可自动调用ld程序完成链接。 调用gcc程序的语法格式&#xff…

Android Studio APP开发入门之对话框Dialog的讲解及使用(附源码 包括提醒对话框,日期对话框,时间对话框)

运行有问题或需要源码请点赞关注收藏后评论区留言~~~ 一、提醒对话框 AlertDialog名为提醒对话框&#xff0c;它是Android中最常用的对话框&#xff0c;可以完成常见的交互操作&#xff0c;例如提示&#xff0c;确认&#xff0c;选择等功能&#xff0c;由于AlertDialog没有公开…

CLRNet: Cross Layer Refinement Network for Lane Detection——论文简述

一、简介 CLRNet充分利用了低层次特征和高层次特征&#xff0c;因为两者是互补的&#xff0c;先基于高层次特征侦测道路&#xff0c;再基于底层次特征进行调优&#xff1b;由于遮挡的存在&#xff0c;使用ROIGather进行全局信息的收集&#xff0c;在ROI道路特征和全局特征图之…

SaaS 架构基础理论(一)

SaaS架构基础理论1、背景2、SaaS商业模式2.1、什么是SaaS2.2、SaaS软件的优势&#xff1a;2.3、SaaS劣势&#xff1a;3.SaaS应用架构3.1、SaaS成熟度模型3.2、SaaS成熟模型分级3.2.1、Level1 定制开发3.2.2、Level2 可配置3.2.3、Level3 高性能的多租户架构3.2.4、Level4 可伸缩…

【Docker】Docker安装与入门

Docker入门与基础命令 Docker简介 Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中&#xff0c;然后发布到任何流行的 Linux或Windows操作系统的机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xf…

Zookeeper几种应用

分布式锁 master-worker模式 涉及三种角色&#xff1a; 1. master&#xff0c;用于检测新的task、worker的添加&#xff0c;将新的task分配给worker处理 2. worker&#xff0c;将自己注册到系统&#xff0c;被master发现后&#xff0c;监控task 3. client&#xff0c;客户…

ARM pwn 入门 (3)

由于网上的ARM pwn题很少很难找&#xff0c;因此这里拿ROP Emporium的8道题做练习&#xff0c;这个网站有包含x86-64、x86-32、MIPS、ARM共4种架构的elf文件可以做。 1. ret2win 注意&#xff1a;在执行需要动态链接库加载的ARM elf文件时&#xff0c;如果直接使用qemu-arm x…

(免费分享)基于javaweb,ssm旅游景点预定系统

源码获取&#xff1a;关注文末gongzhonghao&#xff0c;输入003领取下载链接 IDEA开发工具,数据库&#xff1a;mysql&#xff0c;Tomcat8 采用&#xff1a;springmvcspringmybatis框架 &#xff08;1&#xff09;用户信息管理模块 用户信息管理模块分为后台管理员信息的维护…

zlMediaKit 3 socket模块--怎么封装socket,怎么connect listen/bind write read

socket.cpp socket.h socket SockInfo类&#xff0c;有四个获取四元组信息的虚函数一个获取自身标识符的虚函数 shared_from_this 原理关于boost中enable_shared_from_this类的原理分析 - 阿玛尼迪迪 - 博客园 (cnblogs.com) shared_ptr<Tp> shared_from_this() { re…

RabbitMQ学习(一)

目录&#xff1a; &#xff08;1&#xff09;什么是消息队列 &#xff08;2&#xff09;为什么要使用消息队列 &#xff08;3&#xff09;RabbitMQ特点 &#xff08;4&#xff09;RabbitMQ的安装 &#xff08;5&#xff09;RabbitMQ常用命令 &#xff08;6&#xff09;Ra…

【HTML】标签简单融合运用

&#x1f60a;博主页面&#xff1a;鱿年年 &#x1f449;博主推荐专栏&#xff1a;《WEB前端》&#x1f448; ​&#x1f493;博主格言&#xff1a;追风赶月莫停留&#xff0c;平芜尽处是春山❤️ 一、目录文件夹 1.在vscode建立一个新的目录文件夹如15-综合案例 2.将imag…

图的存储结构

图的存储结构 1.邻接矩阵表示法 设图G (V, E)是具有n个顶点的图&#xff0c;顶点顺序依次为{v1,v2,v3.......} 设a[N][N]为 n 阶方阵 G 的邻接矩阵具有此种性质&#xff1a; 若a[i][j]1&#xff0c;则存在边(vi, vj)或者弧<vi, vj> (即两点之间存在边或弧)若a[i][j]0…

day01 计算机基础和环境搭建

day01 计算机基础和环境搭建 课程目标&#xff1a;让大家了解计算机基础知识并完成python的环境搭建 课程概要&#xff1a; 计算机基础 编程的本质 python的介绍 python环境的搭建 1.计算机基础 1.1 基本概念 计算机的组成 计算机的组计算机是由多个硬件组合而成&#…

快2023了你不会还没学uni-app吧?(uniapp开发快速上手,uniapp项目创建,基础目录介绍)

uniapp新人上手指南前言开发工具快速尝鲜—创建uni-app项目项目基础目录介绍最后前言 uni-app 是一个使用 Vue.js (opens new window)开发所有前端应用的框架&#xff0c;开发者编写一套代码&#xff0c;可发布到14个平台&#xff0c;听起来是不是非常厉害&#xff0c;如果你后…

【论文阅读】Semi-supervised Sequence Learning半监督序列学习

【论文阅读】Semi-supervised Sequence Learning半监督学习 前言 半监督学习(Semi-Supervised Learning&#xff0c;SSL) 是模式识别和机器学习领域研究的重点问题&#xff0c;是监督学习与无监督学习相结合的一种学习方法。半监督学习使用大量的未标记数据&#xff0c;以及同…

别让 Linux 成为拿offer的阻碍

文章目录前言目录结构VI/VIM 编辑器是什么一般模式编辑模式&#xff08;插入模式&#xff09;命令模式模式间转换常用基础命令&#xff08;重要&#xff09;帮助命令man 获得帮助信息help 获得 shell 内置命令的帮助信息type 查看某命令是内置命令还是外部命令常用快捷键文件目…