两种交换排序算法--冒泡,快速

目录

1.冒泡排序原理

2.快速排序原理

3.冒泡代码实现

4.快速排序代码实现


1.冒泡排序原理

冒泡排序(Bubble Sort)是一种简单的排序算法,基本思想是通过反复交换相邻的元素,直到整个序列有序。它的名字来源于较大的元素像气泡一样“浮”到序列的顶部。

原理:

  1. 初始状态:我们从数组的第一个元素开始,比较相邻的两个元素。如果第一个元素大于第二个元素,就交换它们的位置;如果不大,则继续比较下一对元素。

  2. 第一轮排序:通过一轮比较后,最大的元素会被“冒泡”到数组的最后面。

  3. 继续排序:接着,我们对剩下的未排序部分继续进行类似的比较和交换,直到剩下的部分只有一个元素,意味着数组已经排序完成。

示例

假设有一个数组 [5, 2, 9, 1, 5, 6],我们来演示一下冒泡排序的过程。

  • 第一次遍历:

    • 比较 52,交换,得到 [2, 5, 9, 1, 5, 6]
    • 比较 59,不交换
    • 比较 91,交换,得到 [2, 5, 1, 9, 5, 6]
    • 比较 95,交换,得到 [2, 5, 1, 5, 9, 6]
    • 比较 96,交换,得到 [2, 5, 1, 5, 6, 9]
    • 第一轮结束,最大元素 9 已经“冒泡”到最后。
  • 第二轮遍历:

    • 比较 25,不交换
    • 比较 51,交换,得到 [2, 1, 5, 5, 6, 9]
    • 比较 55,不交换
    • 比较 56,不交换
    • 第二轮结束,最大元素 6 已经排好位置。

以此类推,直到所有元素都排好顺序。

时间复杂度

  • 最好的情况(已经有序):O(n)
  • 最坏的情况(逆序):O(n²)
  • 平均情况:O(n²)

虽然冒泡排序简单易懂,但由于其时间复杂度较高,通常在处理大数据时效率不高。

2.快速排序原理

快速排序(Quick Sort)是一种效率很高的排序算法,采用分治法(Divide and Conquer)的策略。它通过选择一个“基准”元素(pivot),然后将数组分成两部分:一部分比基准小,另一部分比基准大。接着递归地对这两部分分别进行快速排序,最终得到有序数组。

快速排序的基本原理:

  1. 选择基准元素:从数组中选择一个元素作为“基准”(pivot)。基准的选择方式可以有多种,比如选择第一个元素、最后一个元素、随机选择等。

  2. 分区操作:将数组重新排列,确保基准元素左边的元素都比它小,右边的元素都比它大。此时,基准元素已经排好位置了。

  3. 递归排序:对基准元素左边和右边的子数组分别进行快速排序。

  4. 终止条件:当子数组的长度为1或0时,递归终止,因为已经有序。

示例

假设我们有一个数组 [10, 7, 8, 9, 1, 5],我们来演示一下快速排序的过程。我们选择最后一个元素 5 作为基准。

  • 第一轮分区

    • 从左到右扫描数组,将小于基准元素的放左边,大于基准元素的放右边。最终,数组被分为 [1, 5, 8, 9, 7, 10],基准 5 排在了正确的位置。
    • 此时,基准元素 5 处于正确位置,左边的部分 [1] 和右边的部分 [8, 9, 7, 10] 需要继续排序。
  • 递归对左部分排序:左边部分只有一个元素 [1],已经有序,不需要做任何操作。

  • 递归对右部分排序:右边部分 [8, 9, 7, 10],选择基准元素 10

    • 分区后得到 [8, 9, 7, 10],基准元素 10 排在了正确的位置。
    • 然后继续对 [8, 9, 7] 排序。
  • 继续递归分区

    • [8, 9, 7] 选择基准 7,分区后得到 [7, 9, 8]
    • [9, 8] 进行排序,最终得到 [7, 8, 9]

经过递归排序,最终得到有序的数组 [1, 5, 7, 8, 9, 10]

快速排序的时间复杂度

  • 最优情况:当每次分区操作都能将数组均匀分成两部分时,时间复杂度是 O(n log n)。
  • 最坏情况:当数组已经是升序或降序时,每次分区只能将一个元素排到正确位置,时间复杂度为 O(n²)。
  • 平均情况:O(n log n),这是最常见的情况,且快速排序在大多数情况下都非常高效。

空间复杂度
快速排序的空间复杂度通常为 O(log n),因为递归的深度最多为 log n(最好的情况下),但它是一个原地排序算法,不需要额外的存储空间。

优缺点

  • 优点:快速排序通常比其他 O(n log n) 排序算法(如归并排序)更高效,特别是对于大规模数据。
  • 缺点:最坏情况下时间复杂度较高(O(n²)),但在实际应用中,通过优化基准元素的选择(比如三数取中法)可以有效避免这种情况。

3.冒泡代码实现

#include <stdio.h>
#include <stdlib.h>
#include <time.h>//冒泡排序typedef int ElemType;//顺序表
typedef struct SqList {ElemType* data;//指针,指向一块内存的起始地址int length;//存储动态数组的长度
}SqList;//顺序表初始化
void initSqList(SqList& L, int len) {L.length = len;L.data = (ElemType*)malloc(sizeof(ElemType) * L.length);//分配空间srand(time(NULL));//随机数生成for (int i = 0; i < L.length; i++){L.data[i] = rand() % 100;//随机生成数字存入顺序表,对100取余是为了规范存入的数据是0-99}
}//顺序表打印
void printSqList(SqList L) {for (int i = 0; i < L.length; i++){printf("%3d", L.data[i]);}printf("\n");
}void swap(ElemType& a, ElemType& b) {ElemType temp = a;a = b;b = temp;
}//冒泡排序顺序表中的元素
void bubbleSort(ElemType* arr, int length) {for (int i = 0; i < length - 1; i++) {   //外层循环,控制循环次数,最多n-1次bool flag = false;      // 标记本趟排序是否发生交换for (int j = length - 1; j > i; j--) {  //内层循环,从后往前通过比较冒出本趟最小元素if (arr[j - 1] > arr[j]) {          //小于前一个元素则交换swap(arr[j - 1], arr[j]);flag = true;}}if (flag == false) {   //本趟没有交换,说明有序,结束return;}}
}int main() {SqList L;//定义一个顺序表initSqList(L, 10);//初始化顺序表,分配10个空间printSqList(L);//打印顺序表中的值	bubbleSort(L.data, 10);//将顺序表进行排序printSqList(L);return 0;
}

4.快速排序代码实现


#include <stdio.h>
#include <stdlib.h>
#include <time.h>//快速排序typedef int ElemType;//顺序表
typedef struct SqList {ElemType* data;//指针,指向一块内存的起始地址int length;//存储动态数组的长度
}SqList;//顺序表初始化
void initSqList(SqList& L, int len) {L.length = len;L.data = (ElemType*)malloc(sizeof(ElemType) * L.length);//分配空间srand(time(NULL));//随机数生成for (int i = 0; i < L.length; i++){L.data[i] = rand() % 100;//随机生成数字存入顺序表,对100取余是为了规范存入的数据是0-99}
}//顺序表打印
void printSqList(SqList L) {for (int i = 0; i < L.length; i++){printf("%3d", L.data[i]);}printf("\n");
}void swap(ElemType& a, ElemType& b) {ElemType temp = a;a = b;b = temp;
}// 分割数组
int partition(ElemType* arr, int low, int high) {ElemType pivot = arr[low];         //将当前第一个元素作为枢轴元素,划分数组while (low < high) {               //外层循环,low和high相遇时为枢轴元素的最终位置while (low < high && arr[high] >= pivot) //从后往前找到第一个小于枢轴的元素跳出循环--high;arr[low] = arr[high];    //将小于枢轴的元素移到左端while (low < high && arr[low] <= pivot)  //从前往后找到第一个大于枢轴的元素跳出循环++low;arr[high] = arr[low];    //将大于枢轴的元素移到右端}arr[low] = pivot;   //枢轴元素放入最终位置return low;         //返回枢轴的最终位置
}// 快速排序顺序表中的元素
void quickSort(ElemType* arr, int low, int high) {if (low < high) {    //递归结束条件//将表分为两个子表,枢轴元素是中间值,左子表小于它,右子表大于它int pivotpos = partition(arr, low, high); //枢轴元素已放入最终位置quickSort(arr, low, pivotpos - 1);  //依次递归处理两个子表quickSort(arr, pivotpos + 1, high);}
}int main() {SqList L;//定义一个顺序表initSqList(L, 10);//初始化顺序表,分配10个空间printSqList(L);//打印顺序表中的值quickSort(L.data, 0, 9);//将顺序表进行排序printSqList(L);return 0;
}

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

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

相关文章

全程Kali linux---CTFshow misc入门(38-50)

第三十八题&#xff1a; ctfshow{48b722b570c603ef58cc0b83bbf7680d} 第三十九题&#xff1a; 37换成1&#xff0c;36换成0&#xff0c;就得到长度为287的二进制字符串&#xff0c;因为不能被8整除所以&#xff0c;考虑每7位转换一个字符&#xff0c;得到flag。 ctfshow{5281…

vue3学习四

七 标签ref属性 设置标签ref属性&#xff0c;类似于设置标签id。 普通标签 <template name"test4"> <p ref"title" id"title" click"showinfo">VIEW4</p> <View3/><script lang"ts" setup>…

STM32 软件SPI读写W25Q64

接线图 功能函数 //写SS函数 void My_W_SS(uint8_t BitValue) {GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)BitValue); }//写SCK函数 void My_W_SCK(uint8_t BitValue) {GPIO_WriteBit(GPIOA, GPIO_Pin_5, (BitAction)BitValue); }//写MOSI函数 void My_W_MOSI(uint8_t Bit…

pytest-xdist 进行多进程并发测试

在自动化测试中&#xff0c;运行时间过长往往是令人头疼的问题。你是否遇到过执行 Pytest 测试用例时&#xff0c;整个测试流程缓慢得让人抓狂&#xff1f;别担心&#xff0c;pytest-xdist 正是解决这一问题的利器&#xff01;它支持多进程并发执行&#xff0c;能够显著加快测试…

CLion2024.3.2版中引入vector头文件报错

报错如下&#xff1a; 在MacBook端的CLion中引入#include <vector>报 vector file not found&#xff08;引入map、set等也看参考此方案&#xff09;&#xff0c;首先可以在Settings -> Build,Execution,Deployment -> Toolchains中修改C compiler和C compiler的路…

【RocketMQ 存储】- 同步刷盘和异步刷盘

文章目录 1. 前言2. 概述3. submitFlushRequest 提交刷盘请求4. FlushDiskWatcher 同步刷盘监视器5. 同步刷盘但是不需要等待刷盘结果6. 小结 本文章基于 RocketMQ 4.9.3 1. 前言 RocketMQ 存储部分系列文章&#xff1a; 【RocketMQ 存储】- RocketMQ存储类 MappedFile【Rock…

了解传输层TCP协议

目录 一、TCP协议段格式 二、TCP原理 1.确认应答 2.超时重传 3.连接管理 建立连接 断开连接 4.滑动窗口 5.流量控制 6.拥塞控制 7.延时应答 8.捎带应答 9.面向字节流 10.TCP异常情况 TCP&#xff0c;即Transmission Control Protocol&#xff0c;传输控制协议。人如…

第 26 场 蓝桥入门赛

3.电子舞龙【算法赛】 - 蓝桥云课 问题描述 话说这年头&#xff0c;连舞龙都得电子化&#xff01;这不&#xff0c;蓝桥村的老程序员王大爷突发奇想&#xff0c;用LED灯带和一堆传感器鼓捣出了一条“电子舞龙”&#xff0c;它能根据程序指令在村里的广场上“翩翩起舞”。 广…

老游戏回顾:TL2

TL2是一部ARPG游戏&#xff0c;是TL的续作游戏&#xff0c;由位于美国西雅图的Runic Games开发&#xff0c;游戏于2012年9月20日上市&#xff0c;简体中文版于2013年4月10日在国内上市。 2有非常独特的艺术风格&#xff0c;这些在1中就已经形成&#xff0c;经过升级将使这款游…

前端实现 GIF 图片循环播放

前言 使用 img 加载 GIF 图片&#xff0c;内容只会播放一次&#xff0c;之后就会自动暂停&#xff1b; 通过定时器在一段时间后重新加载图片的方式&#xff0c;会导致浏览器内存不断增大&#xff0c;并且可能会有闪烁、卡顿的问题&#xff1b; ImageDecoder WebCodecs API 的…

1-2 面向对象编程方法

1.0 面向对象编程思维 在面向对象风格中&#xff0c;结构体被看做数据&#xff08;data&#xff09;&#xff0c;而操作数据的函数称作方法&#xff08;method&#xff09;。目前函数 和数据是分离的&#xff0c;函数并不直接操作数据&#xff0c;我们需要拿到函数返回的结果&a…

LVGL4种输入设备详解(触摸、键盘、实体按键、编码器)

lvgl有触摸、键盘、实体按键、编码器四种输入设备 先来分析一下这四种输入设备有什么区别 &#xff08;1&#xff09;LV_INDEV_TYPE_POINTER 主要用于触摸屏 用到哪个输入设备保留哪个其他的也是&#xff0c;保留触摸屏输入的任务注册&#xff0c;其它几种种输入任务的注册&…

让文物“活”起来,以3D数字化技术传承文物历史文化!

文物&#xff0c;作为不可再生的宝贵资源&#xff0c;其任何毁损都是无法逆转的损失。然而&#xff0c;当前文物保护与修复领域仍大量依赖传统技术&#xff0c;同时&#xff0c;文物管理机构和专业团队的力量相对薄弱&#xff0c;亟需引入数字化管理手段以应对挑战。 积木易搭…

如何通过 ESPN API 获取 NBA 球队的赛程表

对于 NBA 爱好者和开发者来说&#xff0c;通过 API 获取球队赛程表是一项非常实用的功能&#xff0c;尤其是如果你正在构建一个应用或网站&#xff0c;需要自动化获取比赛安排的情况下。今天&#xff0c;我将为大家介绍如何通过 ESPN 提供的 API 获取 NBA 球队的赛程表。 1. ES…

LM Studio 部署本地大语言模型

一、下载安装 1.搜索&#xff1a;lm studio LM Studio - Discover, download, and run local LLMs 2.下载 3.安装 4.更改成中文 二、下载模型(软件内下载) 1.选择使用代理&#xff0c;否则无法下载 2.更改模型下载目录 默认下载位置 C:\Users\用户名\.lmstudio\models 3.搜…

【开源免费】基于SpringBoot+Vue.JS智能学习平台系统(JAVA毕业设计)

本文项目编号 T 181 &#xff0c;文末自助获取源码 \color{red}{T181&#xff0c;文末自助获取源码} T181&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…

【R语言】环境空间

一、环境空间的特点 环境空间是一种特殊类型的变量&#xff0c;它可以像其它变量一样被分配和操作&#xff0c;还可以以参数的形式传递给函数。 R语言中环境空间具有如下3个特点&#xff1a; 1、对象名称唯一性 此特点指的是在不同的环境空间中可以有同名的变量出现&#x…

黑马 Linux零基础快速入门到精通 笔记

初识Linux Linux简介 提及操作系统&#xff0c;我们可能最先想到的是windows和mac&#xff0c;这两者都属于个人桌面操作系统领域&#xff0c;而Linux则属于服务器操作系统领域。无论是后端软件、大数据系统、网页服务等等都需要运行在Linux操作系统上。 Linux是一个开源的操作…

Golang:精通sync/atomic 包的Atomic 操作

在本指南中&#xff0c;我们将探索sync/atomic包的细节&#xff0c;展示如何编写更安全、更高效的并发代码。无论你是经验丰富的Gopher还是刚刚起步&#xff0c;你都会发现有价值的见解来提升Go编程技能。让我们一起开启原子运算的力量吧&#xff01; 理解Go中的原子操作 在快…

网络安全ITP是什么 网络安全产品ips

DS/IPS都是专门针对计算机病毒和黑客入侵而设计的网络安全设备 1、含义不同 IDS &#xff1a;入侵检测系统&#xff08;发现非法入侵只能报警不能自己过滤&#xff09; 做一个形象的比喻&#xff1a;假如防火墙是一幢大楼的门锁&#xff0c;那么IDS就是这幢大楼里的监视系统…