数据结构:交换排序

news2024/11/26 16:51:33

冒泡排序

起泡排序,别名“冒泡排序”,该算法的核心思想是将无序表中的所有记录,通过两两比较关键字,得出升序序列或者降序序列。

算法步骤

  1. 比较相邻的元素。如果第一个元素大于第二个元素,就交换它们。
  2. 对每一对相邻的元素作相同的操作,从开始第一对到末尾的最后一对。
  3. 针对所有的元素重复以上操作,每次出来最后一个

算法理解

例如,对无序表{49,38,65,97,76,13,27,49}进行升序排序的具体实现过程如图 1 所示:

在这里插入图片描述

图 1 第一次起泡

如图 1 所示是对无序表的第一次起泡排序,最终将无序表中的最大值 97 找到并存储在表的最后一个位置。具体实现过程为:

  1. 首先 49 和 38 比较,由于 38<49,所以两者交换位置,即从(1)到(2)的转变;
  2. 然后继续下标为 1 的同下标为 2 的进行比较,由于 49<65,所以不移动位置,(3)中 65 同 97 比较得知,两者也不需要移动位置;
  3. 直至(4),97 同 76 进行比较,76<97,两者交换位置,如(5)所示;
  4. 同样 97>13(5)、97>27(6)、97>49(7),所以经过一次冒泡排序,最终在无序表中找到一个最大值 97,第一次冒泡结束;

由于 97 已经判断为最大值,所以第二次冒泡排序时就需要找出除 97 之外的无序表中的最大值,比较过程和第一次完全相同。

在这里插入图片描述

经过第二次冒泡,最终找到了除 97 之外的又一个最大值 76,比较过程完全一样,这里不再描述。

通过一趟趟的比较,一个个的“最大值”被找到并移动到相应位置,直到检测到表中数据已经有序,或者比较次数等同于表中含有记录的个数,排序结束,这就是起泡排序。

代码实现

#include "iostream"
using namespace std;

void swap(int *a, int *b){//交换a和b的位置
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}
int main()
{
    int array[8] = {49,38,65,97,76,13,27,49};
    //有多少记录,就需要多少次冒泡,当比较过程,所有记录都按照升序排列时,排序结束
    for (int i = 0; i < 8; i++){
        int key=0;//每次开始冒泡前,初始化 key 值为 0
        //每次起泡从下标为 0 开始,到 8-i 结束
        for (int j = 0; j+1<8-i; j++){
            if (array[j] > array[j+1]){
                key=1;
                swap(&array[j], &array[j+1]);
            }
        }
        //如果 key 值为 0,表明表中记录排序完成
        if (key==0) {
            break;
        }
    }
    for (i = 0; i < 8; i++){
        cout << array[i] << " ";
    }
    return 0;
}

运行结果:

13 27 38 49 49 65 76 97

总结

使用起泡排序算法,其时间复杂度同实际表中数据的无序程度有关。若表中记录本身为正序存放,则整个排序过程只需进行 n-1(n 为表中记录的个数)次比较,且不需要移动记录;若表中记录为逆序存放(最坏的情况),则需要 n-1趟排序,进行 n(n-1)/2 次比较和数据的移动。所以该算法的时间复杂度为O(n2)。

快速排序

快速排序本质上是可以说是冒泡排序基础上的递归分治法,它也是分治算法在排序算法上的一种经典应用。

算法思想

快速排序是通过多次比较和交换来实现有序的。在一次排序中把将要排序的元素分成两个独立的子数组,其中一个子数组的所有元素全大于另一个组数组的所有元素,然后继续递归排序这两部分。

算法思想步骤:

  1. 从序列中挑出一个元素,称之为边界或者基准
  2. 重新排序数列,所有元素比基准值小的放在基准前面,所有元素比基准值大的放在基准后面(相同的数可以放在任意一边)。这个操作结束后,该基准就处于序列的中间位置,这个操作称之为分区操作
  3. 递归吧小于基准元素的组数组和大于基准元素的子数组排序

算法理解

在这里插入图片描述

代码实现

#include "iostream"
using namespace std;

#define MAX 9
//单个记录的结构体
typedef struct {
    int key;
}SqNote;
//记录表的结构体
typedef struct {
    SqNote r[MAX];
    int length;
}SqList;
//此方法中,存储记录的数组中,下标为 0 的位置时空着的,不放任何记录,记录从下标为 1 处开始依次存放
int Partition(SqList *L,int low,int high){
    L->r[0]=L->r[low];
    int pivotkey=L->r[low].key;
    //直到两指针相遇,程序结束
    while (low<high) {
        //high指针左移,直至遇到比pivotkey值小的记录,指针停止移动
        while (low<high && L->r[high].key>=pivotkey) {
            high--;
        }
        //直接将high指向的小于支点的记录移动到low指针的位置。
        L->r[low]=L->r[high];
        //low 指针右移,直至遇到比pivotkey值大的记录,指针停止移动
        while (low<high && L->r[low].key<=pivotkey) {
            low++;
        }
        //直接将low指向的大于支点的记录移动到high指针的位置
        L->r[high]=L->r[low];
    }
    //将支点添加到准确的位置
    L->r[low]=L->r[0];
    return low;
}
void QSort(SqList *L,int low,int high){
    if (low<high) {
        //找到支点的位置
        int pivotloc=Partition(L, low, high);
        //对支点左侧的子表进行排序
        QSort(L, low, pivotloc-1);
        //对支点右侧的子表进行排序
        QSort(L, pivotloc+1, high);
    }
}
void QuickSort(SqList *L){
    QSort(L, 1,L->length);
}
int main() {
    SqList *L = new SqList;
    L->length=8;
    L->r[1].key=49;
    L->r[2].key=38;
    L->r[3].key=65;
    L->r[4].key=97;
    L->r[5].key=76;
    L->r[6].key=13;
    L->r[7].key=27;
    L->r[8].key=49;
    QuickSort(L);
    for (int i=1; i<=L->length; i++) {
        cout << L->r[i].key << " ";
    }
    return 0;
}

运行结果:

13 27 38 49 49 65 76 97

总结

快速排序算法的时间复杂度为O(nlogn),是所有时间复杂度相同的排序方法中性能最好的排序算法。

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

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

相关文章

【LeetCode】粉刷房子

粉刷房子 题目描述算法分析编程代码 链接: 粉刷房子 题目描述 算法分析 编程代码 **class Solution { public:int minCost(vector<vector<int>>& costs) {int n costs.size();vector<vector<int>> dp(n1,vector<int>(3));for(int i 1;i&…

医疗行业温湿度轻松搞定,这个方法太简单了吧!

在现代医疗体系中&#xff0c;保障患者的安全和舒适性是至关重要的任务之一。而温湿度监控系统的引入&#xff0c;为实现这一目标提供了切实可行的解决方案。 通过精准地监测和管理医疗环境中的温度和湿度&#xff0c;医疗机构能够营造出稳定、卫生、舒适的就医环境&#xff0c…

vue2项目搭建全步骤-超级详细

文章目录 环境配置node配置安装Vue CLI ​搭建新项目vue create 搭建新项目方法一&#xff1a;选择第一个就好&#xff08;Default是自动安装&#xff0c;按下回车键进行选择&#xff09;方法二&#xff1a;配置自定义设置第一步&#xff1a;选择 Manually select features第二…

什么是信息孤岛?如何打破信息孤岛?

一文让你看懂&#xff1a;什么是信息孤岛&#xff1f;信息孤岛形成的原因&#xff1f;以及如何打破信息孤岛&#xff1f; 本文重点结合了企业信息系统的需求&#xff0c;给出了整合企业现有信息系统的方法&#xff0c;能有效解决企业信息孤岛的问题&#xff0c;并帮助企业快速…

【学习FreeRTOS】第1章——FreeRTOS入门

1.裸机与RTOS介绍 1.1.裸机与RTOS引入&#xff08;举例&#xff09; 设定情景&#xff1a;小明同学一边打游戏一边恢复女友消息&#xff0c;中途突然肚子疼要上医院 裸机的抽象表达 当紧急情况时&#xff0c;如果当前正在打游戏&#xff0c;那么小明只能打游戏和回复信息的流…

$bus的emit和on执行顺序

需求&#xff1a; 但是发现弹框组件第一次打开时&#xff0c;接收不到信息&#xff0c;第二次再摊开&#xff0c;就收到消息了。 原因是因为&#xff1a; 是因为全局事件总线必须先执行$on,再执行$emit 所以我们在使用$bus.$emit发送消息时&#xff0c;要使用nextTick包裹&…

删除的照片如何恢复?4个方法图文详解!

“刚刚和男朋友吵架不小心把我们的合照都删除了&#xff0c;照片是保存在电脑里的&#xff0c;现在真的很后悔。有什么方法能帮我恢复这些照片吗&#xff1f;真的求求了&#xff01;” 照片承载着人们的美好回忆和愉快过往。当我们把照片导入电脑中&#xff0c;可以更清晰地查看…

JavaScript应用:五子棋游戏实战开发

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责…

在数据链路层扩展以太网

为了避免上一节中形成更大的碰撞域&#xff0c;所以从数据链路层来扩展&#xff1a; 网桥工作在数据链路层&#xff0c;因此网桥具备属于数据链路层范畴的相关能力。   网桥可以识别帧结构。   网桥可以根据帧首部中的目的MAC地址和网桥自身的帧转发表来转发或丢弃所收到的…

IT运维:使用数据分析平台监控PowerStore存储

概述 存储在企业中一直承担着重要的角色&#xff0c;保证数据的安全性更是重中之重。存储的运行是否正常&#xff1f;我们的数据是否安全&#xff1f;存储管理人员的操作是否规范&#xff1f;这些都是企业需要关注的问题。那么该如何确保这些问题能够有效的解决&#xff1f;我们…

STM32基于CubeIDE和HAL库 基础入门学习笔记:蓝牙 WIFI STM32连接阿里云

文章目录&#xff1a; 一&#xff1a;蓝牙模块 1.蓝牙模块透传收发测试程序 bt.h bt.c usart.c main.c 2.蓝牙模块AT指令发送与回复判断程序 usart.c main.c 3.蓝牙模块APP按钮控制应用程序 main.c 4.蓝牙模块APP专业调试测试程序&#xff08;操控界面&#xff1a;按…

2023国赛 高教社杯数学建模ABCDE题思路汇总分析

文章目录 0 赛题思路1 竞赛信息2 竞赛时间3 建模常见问题类型3.1 分类问题3.2 优化问题3.3 预测问题3.4 评价问题 4 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 竞赛信息 全国大学生数学建模…

进样顺序对列排斥能的影响

( A, B )---3*30*2---( 1, 0 )( 0, 1 ) 让网络的输入有3个节点&#xff0c;训练集AB各由6张二值化的图片组成&#xff0c;让AB中各有1个1&#xff0c;排列组合所有可能 &#xff0c;统计迭代次数并排序。 差值结构 A-B 迭代次数 36组平均迭代次数 - 2 1 1*0*0*0*0*0-2*…

qt在vs中编译出现link2001时,不会生成moc文件了

现象&#xff1a; 解决方法&#xff1a; 在对应头文件-属性-配置属性-常规-项类型-改为Qt Meta-Object Compiler (moc) 即可。 有时候不知道啥原因头文件类型变成普通C头文件

深入解析中国供应商API:关键字搜索接口对接与商品数据交互指南

随着电商行业的快速发展&#xff0c;越来越多的企业开始与中国供应商进行合作。而为了实现有效的数据交换和协作&#xff0c;接口对接成为了不可或缺的一环。本文将深入探讨中国供应商API&#xff0c;介绍如何高效地进行接口对接与数据交互&#xff0c;并提供实用的Python示例代…

构建之法 - 软件工程实践教学:每天都向前推进一点点

作者&#xff1a;福州⼤学 汪璟玢⽼师 汪老师&#xff1a;每次都向前推进一点点&#xff0c;哪怕只有一点点&#xff0c;也好过什么都不做。 ​邹老师&#xff1a;对&#xff0c;几个学期下来&#xff0c;就已经超过那些“空想”的团队很远了。坚持下去&#xff01; 汪老师&…

以商业大数据技术助力数据合规流通体系建立,合合信息参编《数据经纪从业人员评价规范》团标

经国务院批准&#xff0c;由北京市人民政府、国家发展和改革委员会、工业和信息化部、商务部、国家互联网信息办公室、中国科学技术协会共同主办的2023 全球数字经济大会于近期隆重召开。由数交数据经纪&#xff08;深圳&#xff09;有限公司为主要发起单位&#xff0c;合合信息…

『C语言初阶』第七章 -初识指针

前言 时隔多日小羊又来给铁汁们更新C语言之初识指针&#xff0c;指针是C语言中一个关键且强大的概念&#xff0c;理解和掌握指针对于编写高效、灵活的程序至关重要。本文将详细解释C语言中的指针&#xff0c;帮助初学者迈出掌握编程世界的第一步。 一、指针是什么&#xff1f;…

无涯教程-Perl - int函数

描述 此函数返回EXPR的整数元素,如果省略则返回$_。 int函数不进行舍入。如果需要将值四舍五入为整数,则应使用sprintf。 语法 以下是此函数的简单语法- int EXPRint返回值 此函数返回EXPR的整数部分。 例 以下是显示其基本用法的示例代码- #!/usr/bin/perl$int_valint…

PromQL实现Actuator获取的JVM指标的Full GC次数监控

Spring Boot 版本需要2.0.0或更高版本。 添加Micrometer Prometheus registry依赖: <dependency><groupId>io.micrometer</groupId><artifactId>micrometer-registry-prometheus</artifactId> </dependency>在application.properties中开…