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

相关文章

Spring Boot 实现 IP 限流的原理、实践与利弊解析

《SpringBoot实现IP限流的原理、实践与利弊解析》在SpringBoot中实现IP限流是一种简单而有效的方式来保障系统的稳定性和可用性,本文给大家介绍SpringBoot实现IP限... 目录一、引言二、IP 限流原理2.1 令牌桶算法2.2 漏桶算法三、使用场景3.1 防止恶意攻击3.2 控制资源

springboot下载接口限速功能实现

《springboot下载接口限速功能实现》通过Redis统计并发数动态调整每个用户带宽,核心逻辑为每秒读取并发送限定数据量,防止单用户占用过多资源,确保整体下载均衡且高效,本文给大家介绍spring... 目录 一、整体目标 二、涉及的主要类/方法✅ 三、核心流程图解(简化) 四、关键代码详解1️⃣ 设置

Nginx 配置跨域的实现及常见问题解决

《Nginx配置跨域的实现及常见问题解决》本文主要介绍了Nginx配置跨域的实现及常见问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来... 目录1. 跨域1.1 同源策略1.2 跨域资源共享(CORS)2. Nginx 配置跨域的场景2.1

Python中提取文件名扩展名的多种方法实现

《Python中提取文件名扩展名的多种方法实现》在Python编程中,经常会遇到需要从文件名中提取扩展名的场景,Python提供了多种方法来实现这一功能,不同方法适用于不同的场景和需求,包括os.pa... 目录技术背景实现步骤方法一:使用os.path.splitext方法二:使用pathlib模块方法三

CSS实现元素撑满剩余空间的五种方法

《CSS实现元素撑满剩余空间的五种方法》在日常开发中,我们经常需要让某个元素占据容器的剩余空间,本文将介绍5种不同的方法来实现这个需求,并分析各种方法的优缺点,感兴趣的朋友一起看看吧... css实现元素撑满剩余空间的5种方法 在日常开发中,我们经常需要让某个元素占据容器的剩余空间。这是一个常见的布局需求

HTML5 getUserMedia API网页录音实现指南示例小结

《HTML5getUserMediaAPI网页录音实现指南示例小结》本教程将指导你如何利用这一API,结合WebAudioAPI,实现网页录音功能,从获取音频流到处理和保存录音,整个过程将逐步... 目录1. html5 getUserMedia API简介1.1 API概念与历史1.2 功能与优势1.3

Java实现删除文件中的指定内容

《Java实现删除文件中的指定内容》在日常开发中,经常需要对文本文件进行批量处理,其中,删除文件中指定内容是最常见的需求之一,下面我们就来看看如何使用java实现删除文件中的指定内容吧... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细介绍3.1 Ja

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

PostgreSQL中MVCC 机制的实现

《PostgreSQL中MVCC机制的实现》本文主要介绍了PostgreSQL中MVCC机制的实现,通过多版本数据存储、快照隔离和事务ID管理实现高并发读写,具有一定的参考价值,感兴趣的可以了解一下... 目录一 MVCC 基本原理python1.1 MVCC 核心概念1.2 与传统锁机制对比二 Postg

SpringBoot整合Flowable实现工作流的详细流程

《SpringBoot整合Flowable实现工作流的详细流程》Flowable是一个使用Java编写的轻量级业务流程引擎,Flowable流程引擎可用于部署BPMN2.0流程定义,创建这些流程定义的... 目录1、流程引擎介绍2、创建项目3、画流程图4、开发接口4.1 Java 类梳理4.2 查看流程图4