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

news2024/9/22 1:34:57

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

《数据结构与算法基础-学习-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 OK

real    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 OK

real    0m0.002s
user    0m0.000s
sys     0m0.002s

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

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

相关文章

Leetcode130. 被围绕的区域

Every day a Leetcode 题目来源&#xff1a;130. 被围绕的区域 本题给定的矩阵中有三种元素&#xff1a; 字母 X&#xff1b;被字母 X 包围的字母 O&#xff1b;没有被字母 X 包围的字母 O。 本题要求将所有被字母 X 包围的字母 O都变为字母 X &#xff0c;但很难判断哪些 …

文献阅读:Semantic Communications for Speech Signals

目录 论文简介动机&#xff1a;为什么作者想要解决这个问题&#xff1f;贡献&#xff1a;作者在这篇论文中完成了什么工作(创新点)&#xff1f;规划&#xff1a;他们如何完成工作&#xff1f;自己的看法(作者如何得到的创新思路) 论文简介 作者 Zhenzi Weng Zhijin Qin Geoffre…

网工知识角|掌握MPLS协议从这五个方面入手

今天IELAB李强伟老师(CCNA&HCIA DATACOM/ CCNP EI/ HCIP DATACOM课程讲师)给大家普及一下【MPLS协议的基本介绍】。 ​ 一、什么是MPLS VPN呢&#xff1f; MPLS VPN 是一种虚拟专用网络&#xff0c;它通过 MPLS 技术将不同位置的用户连接在一起&#xff0c;实现安全、高效…

Seata1.5.2+Nacos分布式事务环境搭建详解

文章目录 一、下载seata server二、配置application.yml三、初始Mysql数据库四、导入初始配置到nacos五、启动测试 本文以seata-server-1.5.2&#xff0c;以配置中心、注册中心使用Nacos&#xff0c;store.modedb&#xff08;mysql&#xff09;为例进行操作。 Seata简介及入门参…

掌握这个操作,数据中心才算入门!

在现代的信息技术&#xff08;IT&#xff09;领域&#xff0c;不间断电源&#xff08;UPS&#xff09;扮演着至关重要的角色&#xff0c;它们是保障数据中心、服务器以及其他关键设备持续高效运行的关键组件之一。 UPS系统的任务是在电力故障、电压波动或其他电力问题发生时&am…

如何判断自己的qt版本呢?

如何判断自己的qt版本呢? 前情提要很简单,按照如下图所示,即可查看当前打开的qtCreator的版本如何打开5.15.2版本的qtCreator呢?安装教程 前情提要 我的电脑已经安装了qt5.14.1,然后我又安装了qt5.15.2,我想尝试一下同一台电脑能否适应两个版本的qt? 当我安装完成qt5.15.2后…

短信验证码服务

使用的是 阿里云 阿里云官网 1.找到 左上角侧边栏 -云通信 -短信服务 2.在快速学习测试处 &#xff0c;按照步骤完成快速学习&#xff0c;绑定要测试的手机号&#xff0c;选专用 【测试模板】&#xff0c;自定义模板需要人工审核&#xff0c;要一个工作日 3.右上角 获取 Acces…

UDS 29 认证服务

UDS协议定义了一套标准的诊断服务&#xff0c;包括会话控制、诊断请求、诊断响应和ECU编程等功能。通过UDS协议&#xff0c;诊断工具可以向ECU发送特定的请求&#xff0c;获取ECU的状态信息和故障码&#xff0c;诊断和解决故障问题。UDS是ISO 14229标准定义的一种通信协议&…

python错误:AttributeError: module ‘pydot‘ has no attribute ‘find_graphviz‘

1.安装pydot-ng 由于pydot里面已经没有这个find_graphviz()方法了&#xff0c;选择安装pydot-ng activate python虚拟环境 pip install pydot-ng2安装graphviz 到graphviz官网上下载exe并点击安装&#xff0c;勾选添加到全局变量。 或者记住安装位置选择手动添加到path变…

Javascript动态添加表格行

1.Javascript如何动态添加表格行 图一 图二 1.首先要找到添加按钮代码&#xff0c;设置id选择器 <button type"button" id"insertRow" class"btn btn-danger" style"background-color: #ca6307;border: none">新增一项&l…

【VTK】 vtkMapper

很高兴在雪易的CSDN遇见你 ,给你糖糖 欢迎大家加入雪易社区-CSDN社区云 前言 本文主要分享VTK中关于vtkMapper的相关知识和使用方法,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~YO </

工时管理:如何创建和管理工时表

工时管理是人力资源和业务管理的重要组成部分&#xff0c;对于项目管理也是不可或缺的。无论是哪种类型的工作&#xff0c;如果有团队或员工&#xff0c;那么你就需要工时表来跟踪时间和费用。 什么是工时表&#xff1f; 工时表是一种物理或电子文档&#xff0c;雇主用它来跟…

OCR多语言识别模型构建资料收集

OCR多语言识别模型构建 构建多语言识别模型方案 合合&#xff0c;百度&#xff0c;腾讯&#xff0c;阿里这四家的不错 调研多家&#xff0c;发现有两种方案&#xff0c;但是大多数厂商都是将多语言放在一个字典里&#xff0c;构建1w~2W的字典&#xff0c;训练一个可识别多种语…

【监控平台 - zabbix】

目录 一、环境搭建 1. zabbix程序结构 2. zabbix-agent支持的协议 3. zabbix监控环境搭建 3.1 安装方式 3.2 配置zabbix官方yum源 3.3 安装服务端与客户端 3.4 安装zabbix-web 3.4.1 cd /etc/yum.repos.d/ 3.4.2 安装依赖源 3.4.3 安装本部件 3.4.4 安装存储数据库…

时序预测 | Matlab实现CNN-XGBoost卷积神经网络结合极限梯度提升树时间序列预测

时序预测 | Matlab实现CNN-XGBoost卷积神经网络结合极限梯度提升树时间序列预测 目录 时序预测 | Matlab实现CNN-XGBoost卷积神经网络结合极限梯度提升树时间序列预测效果一览基本描述程序设计参考资料 效果一览 基本描述 时序预测 | Matlab实现CNN-XGBoost卷积神经网络结合极限…

Effective STL 1.仔细选择你的容器

Effective STL 1.仔细选择你的容器 文章目录 Effective STL 1.仔细选择你的容器迭代器容器分类连续内存容器和基于节点的容器的区别 如何选择容器结语>>>>> 欢迎关注公众号【三戒纪元】 <<<<< 标准序列容器 vector、string、deque 和 list 标准…

【技巧】如何在Excel表格中添加水印?

想要在Excel表格中添加水印展示&#xff0c;但是Excel并没有像word文档一样的直接添加水印的功能&#xff0c;怎么办&#xff1f; 今天小编来分享一个方法&#xff0c;也能实现Excel表格的添加水印~ 1、 打开Excel表格&#xff0c;依次点击菜单栏的“插入” → “文本框” →…

小件固定资产怎么管理好

对于小件固定资产的管理&#xff0c;可以考虑以下几个方面&#xff1a;  建立资产档案&#xff1a;对所有小件固定资产进行登记、编号、分类、评估等工作&#xff0c;建立详细的资产档案。  定期盘点&#xff1a;定期对小件固定资产进行盘点&#xff0c;确保资产账面与实际…

【2022】贝壳找房秋招C++工程师笔试卷1 牛妹的字符串

牛妹的字符串 牛妹拿到了一个只由小写字母组成的字符串s&#xff0c;接下来将字符串执行k次操作&#xff0c;每次操作都会把s中ASCII码最小的字母从s中删除&#xff0c;请返回k次操作之后的字符串s。 参考优秀的网友1&#xff1a;26个小写字母 放在数组里正好由大到小排序。 …

聚合多个电商API接口平台

API接口测试&#xff08;点击免费测试&#xff09; 随着数字化商业时代的到来&#xff0c;API接口已成为电商资源连接利器&#xff0c;也是全球传统互联网企业转型的基础。 2021年 Google Cloud 研究显示&#xff0c;全球互联网企业近3/4的企业持续投入数字化转型&#xff0c…