算法(1) 冒泡排序

本文详细介绍了冒泡排序的基本思想和工作原理,通过实例展示了如何对序列进行从大到小的排序。冒泡排序是一种简单的排序算法,通过两两比较相邻元素并交换来逐步排序。虽然效率较低,时间复杂度为O(N^2),但在学习算法基础知识时是一个很好的起点。文中还提供了冒泡排序的C语言实现代码,适合初学者理解和上手实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在我们生活的这个世界中到处都是被排序过的东东。站队的时候会按照身高排序,考试 的名次需要按照分数排序,网上购物的时候会按照价格排序,电子邮箱中的邮件按照时间排 序……总之很多东东都需要排序,可以说排序是无处不在。

排序算法是我们算法学习中比较基础也比较重要的一部分内容 相信大家也在平常的题目中见过

“从小到大”“从大到小”这样类似的排序要求。很多人刚开始对此的确无从下手,这个时候就需要我们去学习排序算法了。排序算法有:选择排序,快速排序,桶排序,希尔排序,插入排序,冒泡排序,冒泡排序,堆排序,归并排序等等。对于我们刚入门,用的相对多一点的是桶排序,选择排序,冒泡排序,快速排序。今天我们来讲的就是 冒泡排序

冒泡排序的基本思想是:每次比较两个相邻的元素,如果它们的顺序错误就把它们交换过来。

例如我们需要将 12 35 99 18 76 这 5 个数进行从大到小的排序。既然是从大到小排序, 也就是说越小的越靠后,你是不是觉得我在说废话,但是这句话很关键(∩_∩)。

从这里可以看出来,冒泡排序的本质不是对整个序列进行排序,而是通过两两相邻的元素间的比较进行排序,从而达到整个序列的排序,所以咱给他起了个小名“友好邻居排序”。

我们就从上举得例子来讲:

首先比较第 1 位和第 2 位的大小,现在第 1 位是 12,第 2 位是 35。发现 12 比 35 要小

因为我们希望越小越靠后嘛,因此需要交换这两个数的位置。交换之后这 5 个数的顺序是 35 12 99 18 76。

按照刚才的方法,继续比较第 2 位和第 3 位的大小,第 2 位是 12,第 3 位是 99。12 比 99 要小,因此需要交换这两个数的位置。交换之后这 5 个数的顺序是 35 99 12 18 76。

根据刚才的规则,继续比较第 3 位和第 4 位的大小,如果第 3 位比第 4 位小,则交换位 置。交换之后这 5 个数的顺序是 35 99 18 12 76。

最后,比较第 4 位和第 5 位。4 次比较之后 5 个数的顺序是 35 99 18 76 12。

经过 4 次比较后我们发现最小的一个数已经就位(已经在最后一位,请注意 12 这个数 的移动过程),是不是很神奇。现在再来回忆一下刚才比较的过程。每次都是比较相邻的两 个数,如果后面的数比前面的数大,则交换这两个数的位置。一直比较下去直到最后两个数 比较完毕后,最小的数就在最后一个了。就如同是一个气泡,一步一步往后“翻滚”,直到 最后一位。所以这个排序的方法有一个很好听的名字“冒泡排序” 就用如下的图来表示整个过程

 讲到这个地方,我们发现,经过了上述步骤,我们已经成功把最小的那位归位了。那么剩下的几个数怎么办呢?很简单,也一样的这么让他们“泡过去”

好,现在开始“第二趟”,目标是将第 2 小的数归位。首先还是先比较第 1 位和第 2 位, 如果第 1 位比第 2 位小,则交换位置。交换之后这 5 个数的顺序是 99 35 18 76 12。接下来你 应该都会了,依次比较第 2 位和第 3 位,第 3 位和第 4 位。注意此时已经不需要再比较第 4 位和第 5 位。因为在第一趟结束后已经可以确定第 5 位上放的是最小的了。第二趟结束之后 这 5 个数的顺序是 99 35 76 18 12。

“第三趟”也是一样的。第三趟之后这 5 个数的顺序是 99 76 35 18 12。到目前为止,我们已经排好了。

其实按照冒泡排序的原理来讲,我们这个序列其实应该一共要走四趟 但是由于这个数列的碰巧最后一趟已经不需要走了,所以三趟位置即可解决。

“冒泡排序”的原理是:每一趟只能确定将一个数归位。即第一趟只能确定将末位上的 数(即第 5 位)归位,第二趟只能将倒数第 2 位上的数(即第 4 位)归位,第三趟只能将倒 数第 3 位上的数(即第 3 位)归位,而现在前面还有两个位置上的数没有归位,因此我们仍 然需要进行“第四趟”。 “第四趟”只需要比较第 1 位和第 2 位的大小。因为后面三个位置上的数归位了,现在 第 1 位是 99,第 2 位是 76,无需交换。这 5 个数的顺序不变仍然是 99 76 35 18 12。到此排 序完美结束了,5 个数已经有 4 个数归位,那最后一个数也只能放在第 1 位了

最后我们总结一下:如果有 n 个数进行排序,只需将 n-1 个数归位,也就是说要进行 n-1 趟操作。而“每一趟”都需要从第 1 位开始进行相邻两个数的比较,将较小的一个数放 在后面,比较完毕后向后挪一位继续比较下面两个相邻数的大小,重复此步骤,直到最后一 个尚未归位的数。

冒泡排序是个初学者可以使用的排序法,聪明的小伙伴其实应该隐隐约约对他有点熟悉感,为啥呢?因为他的核心本质就是双重嵌套循环(一个循环遍历数组,一个循环遍历相邻的排序)

不难看出冒泡排序的时间复杂度是 O(N^2)(不需要学习数据结构的可以不要在意)。这是 一个非常高的时间复杂度。冒泡排序早在 1956 年就有人开始研究,之后有很多人都尝试过 对冒泡排序进行改进,但结果却令人失望。事实上,大多数情况下不会使用冒泡。

讲了这么多,我们来看看实现冒泡操作的模板代码(个人制作,可能有误)

#include <stdio.h> 
int main() 
{ 
 int a[100],i,j,t,n; 
 scanf("%d",&n); //输入一个数n,表示接下来有n个数
 for(i=1;i<=n;i++){ 
       scanf("%d",&a[i]);  //循环读入n个数到数组a中
 }   
 //冒泡排序的核心部分
 for(i=1;i<=n-1;i++) {   //n个数排序,只用进行n-1趟
 	for(j=1;j<=n-i;j++){  //从第1位开始比较直到最后一个尚未归位的数 核心理解为啥到n-i就可以了
 		if(a[j]<a[j+1]){
 			t=a[j]; a[j]=a[j+1]; a[j+1]=t;//比较大小并交换
		 }
	 }
 }
 for(i=1;i<=n;i++){
 	printf("%d ",a[i]);
 }//输出结果 
 return 0;  
} 

注意一点,我们在代码中说到核心理解到n-1 如果说理解不了,其实也不是个很大的问题,无法理解的童鞋,这个地方也是可以循环遍历到n也是一样的,只是时间上可能会慢一点。

当然 我们这里是用了大多数新手看得懂以及使用的到的 在我们的第一行那里,可以看得出我们创建了一个100容量的数组,我们不一定用得到这么多数据,那么就会造成容量浪费。学过动态分配的伙伴,可以把这里改进成一个动态内存分配来进行优化。

好滴,冒泡排序暂且讲到这里了,点个双击么么哒嘿嘿。

大家可以自己动手操作一下,上手还是比较容易的,大家可以写一些例题找找感觉。

(找不到题目的评论区留言 咱们整几个来QAQ)

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZealSinger

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值