冒泡排序算法及其改进(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

相关文章

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

Python实现微信自动锁定工具

《Python实现微信自动锁定工具》在数字化办公时代,微信已成为职场沟通的重要工具,但临时离开时忘记锁屏可能导致敏感信息泄露,下面我们就来看看如何使用Python打造一个微信自动锁定工具吧... 目录引言:当微信隐私遇到自动化守护效果展示核心功能全景图技术亮点深度解析1. 无操作检测引擎2. 微信路径智能获

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll

Spring Security自定义身份认证的实现方法

《SpringSecurity自定义身份认证的实现方法》:本文主要介绍SpringSecurity自定义身份认证的实现方法,下面对SpringSecurity的这三种自定义身份认证进行详细讲解,... 目录1.内存身份认证(1)创建配置类(2)验证内存身份认证2.JDBC身份认证(1)数据准备 (2)配置依

利用python实现对excel文件进行加密

《利用python实现对excel文件进行加密》由于文件内容的私密性,需要对Excel文件进行加密,保护文件以免给第三方看到,本文将以Python语言为例,和大家讲讲如何对Excel文件进行加密,感兴... 目录前言方法一:使用pywin32库(仅限Windows)方法二:使用msoffcrypto-too