冒泡排序算法及其改进(C语言实现)

2024-08-25 13:08

本文主要是介绍冒泡排序算法及其改进(C语言实现),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、经典冒泡算法

假设有n个数需要排列成非递减数列。冒泡算法的主要思想是
①比较第一个与第二个数,如果第二个数小于第一个数则交换,否则不交换;然后以同样的规则比较第二第三个数,以此类推,比如
在这里插入图片描述

这样就完成了一趟排序,通过不断地交换,第一趟排序进行了n-1次比较就把最大的数交换到了最后。
②遵循①中的规则进行下一趟排序,由于最后一位已经确定是最大值,则第二次只需要n-2次比较既可以把第二大的数交换到倒数第二个位置。
③以此类推,第i趟排序需要经过n-i次比较
其算法具体实现如下:

#include <stdio.h>void sort(int* N,int n){int i,j,k;// 外循环控制趟数,一共需要n-1趟for(i = n - 1; i > 0; i--){// 内循环控制每一趟比较的次数for(j = 0; j < i; j++){// 相邻两个数进行比较,如果前一个数较大则进行交换if(N[j] > N[j + 1]){k = N[j];N[j] = N[j + 1];N[j + 1] = k;}}}
}
int main(int argc, char **argv)
{int N[6] = {25,14,54,63,44,3};int n = 6;sort(N,n);int i;for(i = 0; i < n; i++){printf("%d",N[i]);if(i != n - 1) printf(",");}return 0;
}

运行结果:
在这里插入图片描述

二、冒泡算法的改进

冒泡算法的算法时间复杂度显然为o(n2),效率十分低下。在有些情况下,算法执行若干次后,可能已经是有序序列了,但是上面的冒泡算法已经执行后面的比较,知道执行完n-1趟排序,这样显然不是最佳的方式。这时候我们可以设置一个标记,用来判断一趟排序过后有没有发生交换,如果没有发生交换,则说明数组已经有序了,已经不需要再进行余下的比较

#include <stdio.h>void sort(int* N,int n){int i,j,k,l;// 外循环控制趟数,一共需要n-1趟for(i = n - 1; i > 0; i--){// l初始化为0,用于记录每一趟排序的交换次数,//如果一趟排序过后交换次数依然是0,则表示数组已经是有序的了l = 0;// 内循环控制每一趟比较的次数for(j = 0; j < i; j++){// 相邻两个数进行比较,如果前一个数较大则进行交换if(N[j] > N[j + 1]){// 如果发生了交换,l自增l++;k = N[j];N[j] = N[j + 1];N[j + 1] = k;}}if(l != 0) printf("第%d趟排序,发生了%d次交换\n",n - i,l);else {printf("第%d趟排序,没有发生交换,数组已经有序\n",n - i);break;}}
}
int main(int argc, char **argv)
{int N[6] = {1,2,3,4,5,6};int n = 6;sort(N,n);int i;for(i = 0; i < n; i++){printf("%d",N[i]);if(i != n - 1) printf(",");}return 0;
}

运行结果:
在这里插入图片描述

这是一个比较极端的情况,需要排序的数组本来就是有序的。可以看出程序只执行了一趟排序,而不是传统冒泡排序的n-1趟排序,效率有所提高。

三、冒泡算法的再改进

在某些情况下,如果进行了若干次排序之后,后面的若干个数已经是有序的,那么下一趟排序就只需要比较前面无序的那一段就可以了。所以我们可以设置一个标记用来记录每趟排序最后一个发生交换的位置,下一趟排序值比较到此位置即可。

#include <stdio.h>void sort(int* N,int n){int i,j,k,flag;// 初始化标记为-1flag = n - 1;while(flag > 0){i = flag;flag = 0;for(j = 0; j < i; j++){if(N[j] > N[j + 1]){k = N[j];N[j] = N[j + 1];N[j + 1] = k;flag = j;}}printf("最后一次发生交换的位置为%d\n",flag);}}
int main(int argc, char **argv)
{int N[6] = {2,1,4,3,5,6};int n = 6;sort(N,n);int i;for(i = 0; i < n; i++){printf("%d",N[i]);if(i != n - 1) printf(",");}return 0;
}

运行结果:
在这里插入图片描述

虽然以上两种算法对传统的冒泡排序做了一定程度的优化,但是算法复杂度还是o(n2),所以最好的优化方法就是——能不用冒泡算法就不用冒泡算法,改用算法复杂度小的。

这篇关于冒泡排序算法及其改进(C语言实现)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1105639

相关文章

SpringBoot集成redisson实现延时队列教程

《SpringBoot集成redisson实现延时队列教程》文章介绍了使用Redisson实现延迟队列的完整步骤,包括依赖导入、Redis配置、工具类封装、业务枚举定义、执行器实现、Bean创建、消费... 目录1、先给项目导入Redisson依赖2、配置redis3、创建 RedissonConfig 配

Python的Darts库实现时间序列预测

《Python的Darts库实现时间序列预测》Darts一个集统计、机器学习与深度学习模型于一体的Python时间序列预测库,本文主要介绍了Python的Darts库实现时间序列预测,感兴趣的可以了解... 目录目录一、什么是 Darts?二、安装与基本配置安装 Darts导入基础模块三、时间序列数据结构与

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

Nginx部署HTTP/3的实现步骤

《Nginx部署HTTP/3的实现步骤》本文介绍了在Nginx中部署HTTP/3的详细步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录前提条件第一步:安装必要的依赖库第二步:获取并构建 BoringSSL第三步:获取 Nginx

MyBatis Plus实现时间字段自动填充的完整方案

《MyBatisPlus实现时间字段自动填充的完整方案》在日常开发中,我们经常需要记录数据的创建时间和更新时间,传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏,... 目录前言解决目标技术栈实现步骤1. 实体类注解配置2. 创建元数据处理器3. 服务层代码优化填充机制详

Python实现Excel批量样式修改器(附完整代码)

《Python实现Excel批量样式修改器(附完整代码)》这篇文章主要为大家详细介绍了如何使用Python实现一个Excel批量样式修改器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录前言功能特性核心功能界面特性系统要求安装说明使用指南基本操作流程高级功能技术实现核心技术栈关键函

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja