c语言冒泡排序算法解析

冒泡排序算法:

冒泡排序。就是它进行两个两个的比较如果发生了逆序,就进行交换。这里以大的数字放在最右边,小的在最左边先看一组数字:3,10,5,16,9,12,7,冒泡排序进行就是相邻的元素两两比较。

比较结果:
第一次 3,5,10,9,12, 7, 16
第二次 3,5,9,10,7, 12 ,16
第三次 3,5,9,7,10 ,12 ,16
第四次 3,5,7,9,10, 12, 16

从这里我们就可以看出端倪,在整个的排序过程中,相邻两个进行比较的时候我们要使用一次内部循环,在进行排序操作的时候我们还需要进行一次外部循环,才可以最后得出结果。

源代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
void swap(int arr_01[],int n);
void fuzhi(int arr_03[],int n);
 
int main()
{
	int i;
	int arr[10]={0};
	fuzhi(arr,10);
	for(i=0;i<10;i++)
	{
		printf("排序前(随机产生):arr[%d]=%d \n",i,arr[i]);
	}
	swap(arr,10);
	printf("\n");
	for(i=0;i<10;i++)
	{
		printf("排序后(升序排列):arr[%d]=%d \n",i,arr[i]);
	}
	return 0;
}
void fuzhi(int arr_03[],int n)
{
	int i;
	srand(time(0));
	for(i=0;i<n;i++)
	{
		arr_03[i]=rand()%99+1;
	}
}
	
void swap(int arr_01[],int n)
{
	int i,j,temp;
	for(i=0;i<n-1;i++)//比较的轮数 
	{
		for(j=0;j<n-1;j++)//每进行一轮比较,前一个小的元素和后一个较大的元素交换一下位置 
		{
			if(arr_01[j]>arr_01[j+1])
			{
				temp=arr_01[j];
				arr_01[j]=arr_01[j+1];
				arr_01[j+1]=temp;
			}	
		}	 
	}
}	

运行结果:

核心的算法就是利用了两次for循环:

for(i=0;i<n-1;i++)//比较的轮数 
	{
		for(j=0;j<n-1;j++)//每进行一轮比较,前一个小的元素和后一个较大的元素交换一下位置 
		{
			if(arr_01[j]>arr_01[j+1])
			{
				temp=arr_01[j];
				arr_01[j]=arr_01[j+1];
				arr_01[j+1]=temp;
			}	
		}	 
	}

起初我一直不太理解为啥要用到两次循环,这里借用一位博主的巧妙比喻,理解之后,便豁然开朗。

首先:嵌套是这么理解的。比如你有10棵树,每天都去检查是否生虫子了,连续检查一个月(30天)

用代码表示这个循环就是这样:

for(j=1;j<=30;j++)
	{
		for(i=1;i<=10;i++)
		{
			print("今天是第%d天, 正在检查第%d棵树",j,i);
		}
	}

外层循环用户控制天,内层循环用于控制树,缺一不可,第一天检查十遍,第二天检查十遍,...

也就是j=1的时候内层循环执行一遍,j=2的时候内层循环执行一遍...

对于冒泡排序,可以这样考虑:

外层循环式控制一共有多少个泡需要排序, 这个当然要用循环,内层循环控制把某一个泡放到正确的位置, 这个也要用循环, 因为这个泡要和所有未排序泡比较一遍, 然后才能知道自己应该处的位置

这里有两个点,明白了的话,这道题就明白了。

1. 外层循环: 仅仅控制一共有多少个泡需要排序, 比如代码中a[10], 一共是10个元素

2. 内层循环: 仅仅控制把当前最大的泡放到最后, 也就是一次内层循环,仅仅把最大的那个泡放到最后了而已

把1和2综合起来看,当j=0时,把a数组10个元素中最大的泡放到最后,当j=1时,把a数组10个元素中第二大的元素放到倒数第二个位置,依次类推..直到第10大的元素,即最小的元素放到正数第一个位置,可以这样测试一下,会更加清晰,把第一个循环去掉, 内层循环改为:for(i=0; i< 10; i++) 相当于仅执行上述j=0的一次内层循环, 这个循环的作用是把最大的元素放到最后。

这是我把外层循环注释掉之后的结果,可以看到输出的结果只是把最大的“泡”放到了最后,其他位置没有更改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

不掉头发的程序猿_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值