交换排序(Swap Sort)详解

交换排序Swap Sort详解

  • 冒泡排序
    • 冒泡算法
    • 代码实现
    • 冒泡分析
  • 快速排序
    • 快排算法
    • 代码实现
    • 快排分析

交换类排序主要是通过两两比较待排元素的关键字,若发现与排序要求相逆,则交换之。在这类排序方法中最常见的是起泡排序(冒泡排序)和快速排序,其中快速排序是一种在实际应用中具有很好表现的算法。

冒泡排序

冒泡排序(Bubble Sort) 即比较相邻两元素大小,如果反序,则交换,若按照升序排序,则每次应将数据元素序列中最大元素交换到最后位置,即两两相比较,大的元素向后移动,直至将最大的交换到最后的位置,就像水中气泡一样冒出去,得名冒泡排序。

冒泡算法

起泡排序又称为冒泡排序,起泡排序的思想:

  • 首先,将n个元素中的第一个和第二个进行比较,如果两个元素的位置为逆序,则交换两个元素的位置;进而比较第二个和第三个元素关键字,如此类推,直到比较第n-1个元素和第n个元素为止;
  • 上述过程描述了起泡排序的第一趟排序过程,在第一趟排序过程中,我们将关键字最大的元素通过交换操作放到了具有n个元素的序列的最一个位置上。
  • 然后进行第二趟排序,在第二趟排序过程中对元素序列的前n-1个元素进行相同操作,其结果是将关键字次大的元素通过交换放到第n-1个位置上。
  • 一般来说,第i趟排序是对元素序列的前n-i+1个元素进行排序,使得前n-i+1个元素中关键字最大的元素被放置到第n-i+1个位置上。排序共进行n-1趟,即可使得元素序列按关键字有序。

代码实现

//冒泡排序
public void main(String[] args){int[] arr = new int[]{-12,3,2,34,5,8,1};  //冒泡排序  for(int i = 0;i < arr.length-1;i++){  for(int j = 0;j <arr.length-1-i;j++){  if(arr[j] >arr[j+1]){  int temp = arr[j];  arr[j] = arr[j+1];  arr[j+1] = temp;  }}  }
}

冒泡分析

冒泡排序我们分析他的两种情况:

  1. 最好情况:数据序列排序,那么只进行一次冒泡,比较n此,时间复杂度为O(n).
  2. 最坏情况:数据反序排列或者随机排列,那么数据就会进行n-1此冒泡, 因为我们最后一趟冒泡n已经排好,所以我们要进行n-1此冒泡,大家可以自行画图理解。比较次数和移动次数都是(n-1)+(n-2) +.....+2+1;最后可以得到其时间复杂度为O(n2)。那么我们的冒泡排序即在越接近有序的情况下,他的算法的时间效率就越高,反之,如果我的数据有成千上万个,且刚好反序,那么我的效率就十分的低了。因此,冒泡排序虽然稳定,但是也难免会造成效率低下。那么接下来我们就可以学习另一种高级一点的排序方式,快速排序。

空间效率: 仅使用一个辅存单元O(1)

时间效率: 假设待排序的元素个数为 n,则总共要进行n-1趟排序,对j个元素的子序列进行一趟起泡排序需要进行j-1次关键字比较。由此,起泡排序的总比较次数为:
在这里插入图片描述
因此,起泡排序的时间复杂度为Ο(n^2)

快速排序

快速排序(Quick Sort) 是将分治法运用到排序问题中的一个典型例子,快速排序的基本思想是:

  • 通过一个枢轴(pivot)元素将n个元素的序列分为左、右两个子序列Ll和Lr,其中子序列Ll中的元素均比枢轴元素小,而子序列Lr中的元素均比枢轴元素大,
  • 然后对左、右子序列分别进行快速排序,在将左、右子序列排好序后,则整个序列有序,而对左右子序列的排序过程直到子序列中只包含一个元素时结束,此时左、右子序列由于只包含一个元素则自然有序。

快排算法

用分治法的三个步骤来描述快速排序的过程如下:

  1. 划分步骤:通过枢轴元素 x 将序列一分为二, 且左子序列的元素均小于x,右子序列的元素均大于x;
  2. 治理步骤:递归的对左、右子序列排序;
  3. 组合步骤:无

从上面快速排序算法的描述中我们看到,快速排序算法的实现依赖于按照枢轴元素x对待排序序列进行划分的过程。

对待排序序列进行划分的做法是:使用两个指针low和high分别指向待划分序列r的范围,取low所指元素为枢轴,即 pivot = r[low]。划分首先从high所指位置的元素起向前逐一搜索到第一个比pivot小的元素,并将其设置到low所指的位置;然后从low所指位置的元素起向后逐一搜索到第一个比pivot大的元素,并将其设置到high所指的位置;不断重复上述两步直到low = high为止,最后将pivot设置到low与high共同指向的位置。使用上述划分方法即可将待排序序列按枢轴元素pivot分成两个子序列,当然 pivot 的选择不一定必须是 r[low],而可以是 r[low..high]之间的任何数据元素。

在这里插入图片描述

代码实现

public void main(String[] args){int [] a = {19,2,3,90,67,33,-7,24,3,56,34,5};quickSort(a,0,a.length-1);
}
//快速排序
private void quickSort(int[] a, int low, int high) {if(low<high){int middle = getMiddle(a,low,high);quickSort(a, 0, middle-1);quickSort(a,middle+1,high);}
}
//获取中间下标
private int getMiddle(int[] a, int low, int high) {int temp = a[low];//基准元素while(low<high){while(low<high&&a[high]>=temp){high--;}a[low] = a[high];while(low<high&&a[low]<=temp){low++;}a[high] = a[low];}a[low] = temp;//插入到排序后正确的位置return low;
}

快排分析

快速排序算法因为关键字的比较和交换是跳跃进行的,因此,快速排序算法是不稳定的。当待排序序列元素较多且数据元素随机排列时,快速排序是相当快速的;当待排序序列元素较多且基准值选择不合适时,快速排序则较慢。

  • 时间效率: 快速排序算法的运行时间依赖于划分是否平衡,即根据枢轴元素 pivot 将序列划分为两个子序列中的元素个数,而划分是否平衡又依赖于所使用的枢轴元素。下面我们在不同的情况下来分析快速排序的渐进时间复杂度。

快速排序的最坏情况是每次进行划分时,在所得到的两个子序列中有一个子序列为空。此时,算法的时间复杂度T(n) = Tp(n) + T(n-1),其中Tp(n)是对具有n个元素的序列进行划分所需的时间,由以上划分算法的过程可以得到Tp(n) = Θ(n)。由此,T(n) =Θ(n) + T(n-1) =Θ(n2)。在快速排序过程中,如果总是选择r[low]作为枢轴元素,则在待排序序列本身已经有序或逆向有序时,快速排序的时间复杂度为Ο(n2),而在有序时插入排序的时间复杂度为Ο(n)

快速排序的最好情况是在每次划分时,都将序列一分为二,正好在序列中间将序列分成长度相等的两个子序列。此时,算法的时间复杂度T(n) = Tp(n) + 2T(n/2),由于Tp(n) = Θ(n),所以T(n) = 2T(n/2) +Θ(n),由master method知道T(n) = Θ(n log n)。 在平均情况下,快速排序的时间复杂度 T(n) = kn ㏑ n,其中 k 为某个常数,经验证明,在所有同数量级的排序方法中,快速排序的常数因子 k 是最小的。因此就平均时间而言,快速排序被认为是目前最好的一种内部排序方法。

快速排序的平均性能最好,但是,若待排序序列初始时已按关键字有序或基本有序,则快速排序蜕化为起泡排序,其时间复杂度为Ο(n2)。为改进之,可以采取随机选择枢轴元素pivot的方法,具体做法是,在待划分的序列中随机选择一个元素然后与r[low]交换,再将r[low]作为枢轴元素,作如此改进之后将极大改进快速排序在序列有序或基本有序时的性能,在待排序元素个数n较大时,其运行过程中出现最坏情况的可能性可以认为不存在。

  • 空间效率: 虽然从时间上看快速排序的效率优于前述算法,然而从空间上看,在前面讨论的算法中都只需要一个辅助空间,而快速排序需要一个堆栈来实现递归。若每次划分都将序列均匀分割为长度相近的两个子序列,则堆栈的最大深度为 log n,但是,在最坏的情况下,堆栈的最大深度为n

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

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

相关文章

091 脉冲波形的变换与产生

00 如何获得脉冲波形 01 单稳态触发器 1.分类 2.工作特点&#xff1a; ① 电路在没有触发信号作用时处于一种稳定状态。 ② 在外来触发信号作用下&#xff0c;电路由稳态翻转到暂稳态; ③ 由于电路中RC延时环节的作用&#xff0c;暂稳态不能长保持, 经过一段时间后&#xff0c…

高级排序算法(二):归并排序与堆排序详解

引言 在上一章中&#xff0c;我们探讨了高效的快速排序及其分治思想。这一次&#xff0c;我们将继续探索两种同样重要的排序算法&#xff1a;归并排序&#xff08;Merge Sort&#xff09; 和 堆排序&#xff08;Heap Sort&#xff09;。 它们与快速排序一样&#xff0c;都是O(…

JVM调优之如何排查CPU长时间100%的问题

对于CPU长时间100%的问题&#xff0c;其实有一个比较标准的排查流程&#xff0c;现在模拟一个垃圾回收导致的cup占用率过高的排查方法。 步骤如下&#xff1a; 1.先通过top命令找到消耗cpu很高的进程id 在服务器上输入top&#xff0c;显示如下&#xff1a; 通过top命令定位到…

中间件--MongoDB部署及初始化js脚本(docker部署,docker-entrypoint-initdb.d,数据迁移,自动化部署)

一、概述 MongoDB是一种常见的Nosql数据库&#xff08;非关系型数据库&#xff09;&#xff0c;以文档&#xff08;Document&#xff09;的形式存储数据。是非关系型数据库中最像关系型数据库的一种。本篇主要介绍下部署和数据迁移。 在 MongoDB 官方镜像部署介绍中&#xff…

SkyWalking Helm Chart 4.7.0 安装、配置

https://skywalking.apache.org/events/release-apache-skywalking-kubernetes-helm-chart-4.7.0/https://github.com/apache/skywalking-helm/tree/v4.7.0https://skywalking.apache.org/zh/2020-04-19-skywalking-quick-start/简介 skywalking 是分布式系统的 APM(Applicat…

HTA8998 实时音频跟踪的高效内置升压2x10W免电感立体声ABID类音频功放

1、特征 输出功率(fIN1kHz,RL4Ω&#xff0c;BTL) VBAT 4V, 2x10.6W(VOUT9V,THDN10%) VBAT 4V, 2x8.6W (VOUT9V,THDN1%) 内置升压电路模式可选择:自适应实时音频跟踪 升压(可提升播放时间50%以上)、强制升压 最大升压值可选择&#xff0c;升压限流值可设置 ACF防破音功能 D类…

时间敏感网络与工业通信的融合:光路科技电力专用交换机和TSN工业交换机亮相EP电力展

12月7日&#xff0c;第三十一届中国国际电力设备及技术展览会&#xff08;EP Shanghai 2024&#xff09;暨上海国际储能技术应用展览会在上海新国际博览中心圆满落幕。本届展会以“数字能源赋能新质生产力”为主题&#xff0c;系统地呈现了电力设备行业在技术融合、转型升级及上…

前端请求后端接口报错(blockedmixed-content),以及解决办法

报错原因&#xff1a;被浏览器拦截了&#xff0c;因为接口地址不是https的。 什么是混合内容&#xff08;Mixed Content&#xff09; 混合内容是指在同一页面中同时包含安全&#xff08;HTTPS&#xff09;和非安全&#xff08;HTTP&#xff09;资源的情况。当浏览器试图加载非…

【Golang】Go语言编程思想(六):Channel,第四节,Select

使用 Select 如果此时我们有多个 channel&#xff0c;我们想从多个 channel 接收数据&#xff0c;谁来的快先输出谁&#xff0c;此时应该怎么做呢&#xff1f;答案是使用 select&#xff1a; package mainimport "fmt"func main() {var c1, c2 chan int // c1 and …

SpringBoot【八】mybatis-plus条件构造器使用手册!

一、前言&#x1f525; 环境说明&#xff1a;Windows10 Idea2021.3.2 Jdk1.8 SpringBoot 2.3.1.RELEASE 经过上一期的mybatis-plus 入门教学&#xff0c;想必大家对它不是非常陌生了吧&#xff0c;这期呢&#xff0c;我主要是围绕以下几点展开&#xff0c;重点给大家介绍 里…

算法-字符串-32.最长有效括号

一、题目 二、思路解析 1.思路&#xff1a; 滑动窗口&#xff01;&#xff01;&#xff01; 2.常用方法&#xff1a; 无 3.核心逻辑&#xff1a; 1.特殊情况&#xff1a;当字符串为空或不存在 if(snull||s.length()0)return 0; 2.一般情况 a.记录最长有效括符res&#xff1b;初…

9. Win11上原生运行Ubuntu

本文介绍如何在win11原生系统上运行ubuntu&#xff0c;不需要额外安装虚拟机&#xff0c;以及如何配置网络等。 1.安装正版Win11 由于正版Win11需要钱&#xff0c;网上能破解的win11可能有问题&#xff0c;但是它们的破解工具&#xff0c;却是能正常用的&#xff0c;所以&…

【CSS in Depth 2 精译_075】12.2 Web 字体简介 + 12.3 谷歌字体的用法

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第四部分 视觉增强技术 ✔️【第 12 章 CSS 排版与间距】 ✔️ 12.1 间距设置 12.1.1 使用 em 还是 px12.1.2 对行高的深入思考12.1.3 行内元素的间距设置 12.2 Web 字体 ✔️12.3 谷歌字体 ✔️12.…

【学习笔记】目前市面中手持激光雷达设备及参数汇总

手持激光雷达设备介绍 手持激光雷达设备是一种利用激光时间飞行原理来测量物体距离并构建三维模型的便携式高科技产品。它通过发射激光束并分析反射回来的激光信号&#xff0c;能够精确地获取物体的三维结构信息。这种设备以其高精度、适应各种光照环境的能力和便携性&#xf…

SQL汇总数据:聚集函数

我们经常需要汇总数据而无需实际检索出这些数据&#xff0c;为此SQL提供了专门的函数。使用这些函数&#xff0c;SQL查询能够高效地检索数据&#xff0c;以便进行分析和报表生成。这类检索的例子包括&#xff1a; 确定表中行数&#xff08;或者满足某个条件或包含某个特定值的…

Midjourney基础教程-功能界面详解

基础入门教程&#xff1a; 一.Midjourney快速入门(3步画出你的第一张图&#xff09; 注&#xff1a; 1.平台为大家设置了自动翻译&#xff0c;可以直接写中文提示词&#xff0c;自动翻译成英文。当然要求更准确&#xff0c;大家可以先翻译成英 文在输入进来。 2.提示词如何去…

初识Linux · 日志编写

目录 前言&#xff1a; 日志的简单说明 编写日志 前言&#xff1a; 在线程池部分我们纵观全文&#xff0c;可以发现全文有很多很多的IO流&#xff0c;看起来还是差点意思的&#xff0c;而我们今天提到的日志&#xff0c;是在今后的代码编写中会经常接触&#xff0c;或者说在…

微信小程序做电子签名功能

文章目录 最近需求要做就记录一下。 人狠话不多&#xff0c;直接上功能&#xff1a; 直接搂代码吧,复制过去就可以用&#xff0c;有其他需求自己改吧改吧。 signature.wxml <!-- 电子签名页面 --> <custom-navbar title"电子签名"show-home"{{fals…

【HarmonyOS】使用AVPlayer播放音乐,导致系统其它应用音乐播放暂停 - 播放音频焦点管理

【HarmonyOS】使用AVPlayer播放音乐&#xff0c;导致系统其它应用音乐播放暂停 - 播放音频焦点管理 一、前言 在鸿蒙系统中&#xff0c;对于音乐播放分为几种场景。音乐&#xff0c;电影&#xff0c;音效&#xff0c;闹钟等。当使用AVPlayer播放音乐时&#xff0c;如果不处理…

Linux中inode、软硬连接

磁盘的空间管理 如何对磁盘空间进行管理&#xff1f; 假设在一块大小为500G的磁盘中&#xff0c;500*1024*1024524288000KB。在磁盘中&#xff0c;扇区是磁盘的基本单位&#xff08;一般大小为512byte&#xff09;&#xff0c;而文件系统访问磁盘的基本单位是4KB&#xff0c;因…