数据结构与算法基础-学习-31-交换排序之冒泡排序、快速排序

排序的其他相关知识点和源码分享可以参考之前的博客:   

《数据结构与算法基础-学习-30-插入排序之直接插入排序、二分插入排序、希尔排序》

一、交换排序基本思想

两两比较,如果发生逆序则交换位置,直到所有数据记录都排好序为止。

二、冒泡排序基本思想

每趟不断地将数据记录两两比较,并按照升序或降序规则进行交换。

三、冒泡排序算法实现思路

这里的哨兵起的是临时变量的作用,在交换元素时使用。

我们还是以升序为例。

1、第一趟

一共有7个元素,需要比较6次,因为没有8号位。

(1)1小于2,不要交换,继续

(2)2小于8,不要交换,继续

(3)8大于5,需要交换,继续

(4)8大于4,需要交换,继续

(5)8大于6,需要交换,继续

(6)8大于3,需要交换,6次比较完,已经把最大值8放到了最后一位,那下一趟比较时,就不需要比较8了。

2、第二趟

一共有6个元素需要比较,总共需要比较5次,因为7号位的8已经完成排序。

(1)1小于2,不要交换,继续

(2)2小于5,不要交换,继续

(3)5大于4,需要交换,继续

(4)5小于6,不要需要交换,继续

(5)6大于3,需要交换,5次比较完,已经把最大值6放到了最后一位,那下一趟比较时,就不需要比较6,8了。

3、第三趟

一共有5个元素需要比较,总共需要比较4次,因为6和8已经完成排序。

规律都知道了,我们这就快进一些,跳过了一些对比步骤。

1,2,3,4,5都是升序不需要移动。

(1)5大于3,需要交换,4次比较完,已经把最大值5放到了最后一位,那下一趟比较时,就不需要比较5,6,8了。

4、第四趟

一共有4个元素需要比较,总共需要比较4次,因为5,6和8已经完成排序。

规律都知道了,我们这就快进一些,跳过了一些对比步骤。

1,2,4都是升序不需要移动。

(1)4大于3,需要交换,3次比较完,已经把最大值4放到了最后一位,那下一趟比较时,就不需要比较4,5,6,8了。

5、第五趟

一共有4个元素需要比较,总共需要比较3次,因为4,5,6和8已经完成排序。

1,2,3,4就是升序的,没有交换元素,说明序列已经是有序的,排序完成。

四、冒泡排序算法源码

1、BubbleSortSentrySqQueue

Status BubbleSortSentrySqQueue(SqQueue* Queue)
{JudgeAllNullPointer(Queue);if (Queue->Flag != INT_TYPE_FLAG){return FailFlag;}int*         Array    = (int*)(Queue->Data);int          SwapFlag = 0;QueueLenType i;QueueLenType j;for (i = 1; i < Queue->SqQueueLen - 1; i++)//长度n,比较(n - 1)趟。{SwapFlag = 0;for (j = 1; j < Queue->SqQueueLen - i; j++)//每趟,比较 (n - 第i趟) 次。找个测试数据更明显,好理解{if (Array[j] > Array[j + 1]){Array[0]     = Array[j + 1];Array[j + 1] = Array[j];Array[j]     = Array[0];SwapFlag     = 1;}}if (SwapFlag == 0)//如果某一趟不需要进行交换,说明所有元素都是有序的,退出循环。{break;}}LogFormat(Debug,"Bubble Sort SqQueue OK.\n");return SuccessFlag;
}

五、冒泡排序算法效率

情况时间复杂度是否稳定
最好O(n)稳定
最坏O(n^2)
平均O(n^2)

最好的情况例如冒泡升序排序,数据是升序排列的,只需要比较n-1次即可,不需要移动元素。

最坏的情况例如冒泡升序排序,数据是降序排列的,

(1)需要比较次数为:

长度为n的序列,需要比较n-1次,每次少比一次,直到1为止,可以使用等差求和公式:

((n - 1) + 1) * (n - 1) / 2 = (n^2 - n)/ 2

(2)需要移动次数为:

每比较一次,需要交换一次,交换需要临时变量存放,一共需要三步,所以乘以3。

                Array[0]     = Array[j + 1];Array[j + 1] = Array[j];Array[j]     = Array[0];

(n^2 - n)/ 2 * 3。

六、冒泡排序Linux环境编译测试

[gbase@czg2 Sort]$ time ./TestSort 
2023-9-1--[ Debug ]--Init SqQueue OK
2023-9-1--[ Debug ]--Enter SqQueue OK
2023-9-1--[ Debug ]--Enter SqQueue OK
2023-9-1--[ Debug ]--Enter SqQueue OK
2023-9-1--[ Debug ]--Enter SqQueue OK
2023-9-1--[ Debug ]--Enter SqQueue OK
2023-9-1--[ Debug ]--Enter SqQueue OK
2023-9-1--[ Debug ]--Enter SqQueue OK
2023-9-1--[ Debug ]--Enter SqQueue OK
2023-9-1--[ Debug ]--Enter SqQueue OK
2023-9-1--[ Debug ]--Enter SqQueue OK
2023-9-1--[ Debug ]--Enter SqQueue OK
2023-9-1--[ Debug ]--SqQueue Data   :
Data           : [ 0 ,10 ,9 ,8 ,7 ,6 ,5 ,4 ,3 ,2 ,1 ]
FrontIndex     : 0
RearIndex      : 0
SqQueueLen     : 11
SqQueueMaxLen  : 11
Flag           : INT_TYPE_FLAG
2023-9-1--[ Debug ]--Bubble Sort SqQueue OK.
2023-9-1--[ Info  ]--Sort Function Elapsed Time   : 0 s
2023-9-1--[ Info  ]--SqQueue Data   :
Data           : [ 1 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 ]
FrontIndex     : 0
RearIndex      : 0
SqQueueLen     : 11
SqQueueMaxLen  : 11
Flag           : INT_TYPE_FLAG
2023-9-1--[ Debug ]--Destroy SqQueue OKreal    0m0.002s
user    0m0.000s
sys     0m0.002s

七、快速排序基本思想

快速排序是改进的交换排序。

1、任取一个元素为中心(一般是第一个元素)。

2、所有比它小的元素一律前放,比它大的元素一律后放,形成左右两个子表。

3、对各子表重新选择中心元素并依照上述规则调整。

4、直到每个子表的元素只剩下一个。

八、快速排序算法实现思路

这里的哨兵位也是起到存放临时变量的作用的。

1、第一趟

1号位的3作为中间点,存放在哨兵位0中,那Low位置的元素就是空的了。

哨兵位的3和High的1进行比较,3大于1,将High的1填写到Low上,那样High的位置就空出来了。我们开始从Low找。

哨兵位的3和Low的1进行比较,3大于1,在3的左边,不需要移动,Low向右移动。

哨兵位的3和Low的2进行比较,3大于2,在3的左边,不需要移动,Low向右移动。

哨兵位的3和Low的8进行比较,8大于3,在3的右边,需要移动把Low的8移动到High的位置,Low的位置空了,开始High位置和哨兵进行比较,是不是发现了什么,左边有空位了,就去右边找,找,右边空了,就去左边找,很有规律性。

哨兵位的3和High的8进行比较,8大于3,在3的右边,不需要移动,High向左移动。

哨兵位的3和High的6进行比较,6大于3,在3的右边,不需要移动,High向左移动。

哨兵位的3和High的4进行比较,4大于3,在3的右边,不需要移动,High向左移动。

Low和High重合,说明Low左边的都比3小,右边的都比3大,把3填到Low的位置。

Low左边已经排好序了,我们开始排序右边的这些元素。

2、第二趟

还是以第一个Low的位置为中心点,这样Low的位置就空出来了,哨兵和HIgh为的5进行比较,发现比8小,HIgh左移。

哨兵位的5和High的6进行比较,6大于5,在5的右边,不需要移动,High向左移动。

哨兵位的5和High的4进行比较,5大于4,在5的左边,Low填上4,那High的位置就空出来了,我们开始移动Low。

哨兵位的5和Low的4进行比较,5大于4,在3的左边,不需要移动,Low向右移动。

发现Low和High重合,将哨兵填写到Low上,这一段有序了,整个序列就完成了排序。

九、快速排序算法源码

1、QuickSortPartionSentrySqQueue

将Low到High之间元素根据Low为中间值进行分区,返回中间值的最终索引位置。

//返回中间点索引。
QueueLenType QuickSortPartionSentrySqQueue(SqQueue* Queue, QueueLenType Low, QueueLenType High)
{JudgeAllNullPointer(Queue);int* Array = (int*)(Queue->Data);Array[0]   = Array[Low];while (Low < High){while (Low < High && Array[0] <= Array[High])//大于等于中间点的值放右边。{High--;}Array[Low] = Array[High];while (Low < High && Array[0] > Array[Low])//小于中间点的值放左边。{Low++;}Array[High] = Array[Low];}Array[Low] = Array[0];return Low;
}

2、QuickSortRecurtionSentrySqQueue

void QuickSortRecurtionSentrySqQueue(SqQueue* Queue, QueueLenType Low, QueueLenType High)
{JudgeAllNullPointer(Queue);if (Low >= High)//退出条件,High必须要大于low。{return;}QueueLenType PivotIndex = QuickSortPartionSentrySqQueue(Queue, Low, High);QuickSortRecurtionSentrySqQueue(Queue, Low, PivotIndex - 1);QuickSortRecurtionSentrySqQueue(Queue, PivotIndex + 1, High);
}

十、快速排序算法效率

情况时间复杂度是否稳定
最好O(n * log2^n)不稳定
最坏O(n^2)
平均O(n * log2^n)

1、快速排序不是原地排序,因为递归方法使用了系统栈,不用递归,需要用用户栈实现。

2、快速排序不适用于对原本有序或基本有序的记录序列进行排序。

3、划分元素的选取是影响时间性能的关键。

4、输入数据次序越乱,所选划分值随机性越好,排序速度越快,快速排序不是自然排序方法。

5、升序快速排序算法使用在倒序排序序列上,会触发最坏的情况,使算法退化为冒泡排序。

十一、快速排序Linux环境编译测试

[gbase@czg2 Sort]$ time ./TestSort 
2023-9-1--[ Debug ]--Init SqQueue OK
2023-9-1--[ Debug ]--Enter SqQueue OK
2023-9-1--[ Debug ]--Enter SqQueue OK
2023-9-1--[ Debug ]--Enter SqQueue OK
2023-9-1--[ Debug ]--Enter SqQueue OK
2023-9-1--[ Debug ]--Enter SqQueue OK
2023-9-1--[ Debug ]--Enter SqQueue OK
2023-9-1--[ Debug ]--Enter SqQueue OK
2023-9-1--[ Debug ]--Enter SqQueue OK
2023-9-1--[ Debug ]--Enter SqQueue OK
2023-9-1--[ Debug ]--Enter SqQueue OK
2023-9-1--[ Debug ]--Enter SqQueue OK
2023-9-1--[ Debug ]--SqQueue Data   :
Data           : [ 0 ,10 ,9 ,8 ,7 ,6 ,5 ,4 ,3 ,2 ,1 ]
FrontIndex     : 0
RearIndex      : 0
SqQueueLen     : 11
SqQueueMaxLen  : 11
Flag           : INT_TYPE_FLAG
2023-9-1--[ Debug ]--Quick Sort Sentry SqQueue OK.
2023-9-1--[ Info  ]--Sort Function Elapsed Time   : 0 s
2023-9-1--[ Info  ]--SqQueue Data   :
Data           : [ 4 ,0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ]
FrontIndex     : 0
RearIndex      : 0
SqQueueLen     : 11
SqQueueMaxLen  : 11
Flag           : INT_TYPE_FLAG
2023-9-1--[ Debug ]--Destroy SqQueue OKreal    0m0.002s
user    0m0.000s
sys     0m0.002s

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

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

相关文章

大模型理解之CLIP

前言 2021年2月份&#xff0c;CLIP模型被提出&#xff0c;想法很简单&#xff0c;性能高效&#xff0c;而且具备很好的泛化性。我在这里简单谈论下我对CLIP模型的理解&#xff0c;以及发现的一些问题。 我是在沐神的视频中了解的CLIP, 里面提到CLIP最大的贡献在于打破了固定类…

四轴飞行器的电池研究(MatlabSimulink仿真)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

全球免费编程教育网站:Code.org

全球免费编程教育网站&#xff1a;Code.org 官网地址注册使用 你还在为小朋友的编程教育而发愁吗&#xff1f; 你还在为小朋友放假无聊而头疼吗&#xff1f; 他来了他来了&#xff0c;全球免费编程教育网站来了。 2013年成立的Code.org是一个非营利组织。 它致力于为年轻女子、…

Xilinx UltraScale架构之可配置逻辑块CLB

目录 一、概览 二、UltraScale架构 2.1 UltraScale/UltraScale特点 2.2 与7系列CLB差异 三、 CLB结构 3.1 LUT 3.2 FF 3.3 多路选择器Multiplexers 3.4 进位链Carry Chain 四、应用 4.1 分布式RAM 4.2 移位寄存器 4.3 进位链Carry Chain 五、参考资料 一、概览 二…

专门针对开发人员,攻击者利用Rust获取操作系统信息

近日&#xff0c;研究人员在 Rust 编程语言的 crate 注册表中发现了一些恶意软件包&#xff0c;专门针对开发人员。 Phylum 在上周发布的一份报告中称&#xff0c;这些库是由一个名为 "amaperf "的用户在 2023 年 8 月 14 日至 16 日之间上传的。现已删除的软件包名…

【LeetCode-中等题】114. 二叉树展开为链表

文章目录 题目方法一&#xff1a;前序遍历&#xff08;构造集合&#xff09; 集合&#xff08;构造新树&#xff09;方法二&#xff1a;原地构建方法三&#xff1a;前序遍历--迭代&#xff08;构造集合&#xff09; 集合&#xff08;构造新树&#xff09; 题目 方法一&#x…

el-select 选择一条数据后,把其余数据带过来

1. 案例&#xff1a; ps: 票号是下拉框选择&#xff0c;风险分类、场站名称以及开始时间是选择【票号】后带过来的。 2. 思路: 使用官网上给的方法&#xff0c;选择之后&#xff0c;触发change方法从而给其余字段赋值 3. 代码 <el-form-itemlabel"票号&#xff1a;&…

buildAdmin的使用笔记

安装buildAdmin 下载完整包&#xff0c;解压进入 buildadmin 的文件夹&#xff0c; 输入命令 composer install 启动的时候使用&#xff0c; php think run 就可以了 为什么启动只需要&#xff0c; php think run 这种启动方式&#xff0c; 我是头一回看见 &#xff0c;后来才…

Android 手游聚合SDK小知识(一)

Android 手游聚合SDK小知识(一) Android 手游聚合SDK小知识(二) 聚合分包 前言 回头想想&#xff0c;在安卓游戏SDK这个领域&#xff0c;我也呆了4年了&#xff0c;从啥都不懂的小菜鸟&#xff0c;逐渐靠自己不断学习&#xff0c;对这个行业也算有了一些理解&#xff0c;趁着…

[贪心] 拼接最小数

这道题思路并不难&#xff0c;我主要想学习其一些对于字符串的处理。 代码如下&#xff1a; #include <iostream> #include <string> #include <algorithm> using namespace std;const int MAXN 10000; string nums[MAXN];bool cmp(string a, string b) {…

useEffect 不可忽视的 cleanup 函数

在 react 开发中&#xff0c; useEffect 是我们经常会使用到的钩子&#xff0c;一个基础的例子如下&#xff1a; useEffect(() > {// some code here// cleanup 函数return () > {doSomething()} }, [dependencies])上述代码中&#xff0c; cleanup 函数的执行时机有如下…

设计模式第九讲:常见重构技巧 - 去除不必要的!=

设计模式第九讲&#xff1a;常见重构技巧 - 去除不必要的! 项目中会存在大量判空代码&#xff0c;多么丑陋繁冗&#xff01;如何避免这种情况&#xff1f;我们是否滥用了判空呢&#xff1f;本文是设计模式第九讲&#xff0c;讲解常见重构技巧&#xff1a;去除不必要的! 文章目录…

Swift 中的动态成员查找

文章目录 前言基础介绍基础示例1. 定义一个动态成员访问类&#xff1a;2. 访问嵌套动态成员&#xff1a; 使用 KeyPath 的编译时安全性KeyPath 用法示例KeyPath 进阶使用示例1. 动态访问属性&#xff1a;2. 结合可选属性和 KeyPath&#xff1a;3. 动态 KeyPath 和字典&#xff…

MySQL8.0.22安装过程记录(个人笔记)

1.点击下载MySQL 2.解压到本地磁盘&#xff08;注意路径中不要有中文&#xff09; 3.在解压目录创建my.ini文件 文件内容为 [mysql] # 设置mysql客户端默认字符集 default-character-setutf8[mysqld] # 设置端口 port 3306 # 设计mysql的安装路径 basedirE:\01.app\05.Tool…

《爵士乐史》乔德.泰亚 笔记

第一章 【美国音乐的非洲化】 【乡村布鲁斯和经典布鲁斯】 布鲁斯&#xff1a;不止包括忧愁、哀痛 十二小节布鲁斯特征&#xff1a; 1.乐型&#xff08;A:主、B:属、C/D:下属&#xff09;&#xff1a;A→A→B→A→C→D→A→A 2.旋律&#xff1a;大三、小三、降七、降五 盲人…

Matlab(GUI程式设计)

目录 1.MatlabGUI 1.1 坐标区普通按钮 1.1.1 对齐组件 1.1.2 按钮属性 1.1.3 脚本说明 1.1.4 选择呈现 1.3 编译GUI程序 在以前的时候&#xff0c;我们的电脑还是这样的 随着科技的不断进步&#xff0c;我们的电脑也发生着翻天覆地的改变1990s&#xff1a; 在未来&#xff0c…

优化爬虫请求:如何选择合适的爬虫ip轮换策略?

在进行爬虫任务时&#xff0c;使用隧道爬虫ip并采用合适的轮换策略可以提高稳定性和效率。选择合适的隧道爬虫ip轮换策略可以优化您的爬虫请求过程。 1、考量目标网站特点 不同网站对于频繁请求可能有不同限制或反爬机制。 了解目标网站是否存在IP封禁、验证码等问题&#xff…

2359. 找到离给定两个节点最近的节点;1781. 所有子字符串美丽值之和;2406. 将区间分为最少组数

2359. 找到离给定两个节点最近的节点 核心思想:统计node1和node2分别到每个点的距离&#xff0c;然后在枚举每个点统计结果。关键在于如何统计node到每个点的距离&#xff0c;首先是初始化为inf很重要&#xff0c;因为在枚举的时候&#xff0c;因为是inf代表了这个节点无法到达…

VC++使用Microsoft Speech SDK进行文字TTS朗读

Microsoft Speech SDK下载地址 https://www.microsoft.com/en-us/download/details.aspx?id10121 需要msttss22L.exe、SpeechSDK51.exe、SpeechSDK51LangPack.exe三个&#xff0c;下载后全部安装 使用VS2005建立一个win32控制台项目 朗读"hello word"、中文“你好”…

Flink的checkpoint是怎么实现的?

分析&回答 Checkpoint介绍 Checkpoint容错机制是Flink可靠性的基石,可以保证Flink集群在某个算子因为某些原因(如 异常退出)出现故障时,能够将整个应用流图的状态恢复到故障之前的某一状态,保证应用流图状态的一致性。Flink的Checkpoint机制原理来自“Chandy-Lamport alg…