1.气泡法排序能解决的问题
2.气泡法排序
2.1概述算法思路
2.2算法理解(双循环代码实现)
2.3例题(cr.北理作业-33.【字符】组成最大数)
3.战胜北理工的恶龙
3.1完整代码
3.2简述思路
1.气泡法排序能解决的问题
气泡法排序是一种比较简单的排序方法,它能为n个数进行排序(从大到小/从小到大);
应用情形:把一组数从大到小排序/输出一组数中最大的五个数/对两组数对应位上的数依次进行大小比较(先要把两组数按序排列)。
2.气泡法排序
2.1概述算法思路
依次比较相邻的两个数,将大数放在前面,小数放在后面。
即首先比较第1个和第2个数,将大数放前,小数放后。
然后比较第2个数和第3个数,依旧将大数放前,小数放后,如此继续,直至比较最后两个数,将大数放前,小数放后。
至此,第一轮比较结束,最小的数已成功找出,并放在了最后一位上(所以下一轮排序最后一位不参加了)。
重复以上过程,仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再大于第2个数),将大数放前,小数放后。
一直比较到最后一位前的一对相邻数,将大数放前,小数放后,第二轮结束,在倒数第二个数中得到一个新的最小数(即整个数列中第二小的数)。
如此下去,直至最终完成从大到小的排序。
命名由来: 由于在排序过程中总是大数往前放,小数往后放,相当于较大的气泡往上冒,较小的气泡往下沉,所以也称作冒泡法(Bubble sort)。

2.2算法理解(双循环代码实现)
若要排序的数有n个,则需要n-1轮排序(下述代码中由j控制);在第j轮排序中,从第1个数开始,相邻两个数进行比较,若不符合所要求的顺序,则交换两个数的位置;此过程中,第1个数与第2个数比较,第2个数与第3个数比较,······,第n-j个数与第n+1-j个数比较,共比较n-j次;此时第n+1-j个位置上的数已按要求排好,所以不再参加下一轮的比较和交换操作。
以“n=4,4个数是0,2,3,9,从大到小排序”为例:

所以一共进行n-1轮排序,每一轮进行到第n-j个数与第n+1-j个数的比较为止,共比较n-j次······都是如此推算确定的。
完整代码:(以“n=4,4个数是0,2,3,9,从大到小排序”为例)
#include <stdio.h>
int main()
{
//i是数组下标;j是表示在进行的是第几轮排序;
//m是暂存两相邻数中较大数的变量(用于两数交换);n是数组中数的个数;
int i,j,m,n=4;
int a[4]={0,2,3,9};
//进行第j轮排序;
for(j=1;j<=n-1;j++)
{
//遍历数组中的数,使相邻两数都进行一次比较;
for(i=0;i<n-j;i++)
{
if(a[i]<a[i+1])
{
m=a[i];
a[i]=a[i+1];
a[i+1]=m;
}
}
}
//输出验证一下结果是否正确;
for(i=0;i<n;i++)
{
printf("%d",a[i]);
}
return 0;
}
2.3例题(cr.北理作业-33.【字符】组成最大数)
题目:

完整代码:
#include <stdio.h>
#include <string.h>
int main()
{
char a[10];
int j,i,n,M;
scanf("%s",a);
n=strlen(a);
for(j=1;j<=n-1;j++){
for(i=0;i<n-j;i++){
if(a[i]<a[i+1])
{ M=a[i];
a[i]=a[i+1];
a[i+1]=M;
}
}
}
printf("%s\n",a);
return 0;
}
3.战胜北理工的恶龙
终于来到了激动人心的北理工被恶龙毁灭的环节!!(bushi)
这是我个人觉得很有趣的一道题,也许你也能因为这道题爱上c语言+-+
题目:

3.1完整代码
#include <stdio.h>
#define N 100
int main(){
int j,i,n,m,p,M,score=0;
int dragon_head[N],hero[N];
scanf("%d %d",&n,&m);
for(i=0;i<n;i++)
scanf("%d",&dragon_head[i]);
for(j=0;j<m;j++)
scanf("%d",&hero[j]);
//分别给恶龙和勇士两组数列进行从小到大的排序(气泡法);
for(p=1;p<=n-1;p++)
{for(i=0;i<n-p;i++)
{if(dragon_head[i]>dragon_head[i+1])
{M=dragon_head[i];
dragon_head[i]=dragon_head[i+1];
dragon_head[i+1]=M;
}
}
}
for(p=1;p<=m-1;p++)
{for(j=0;j<m-p;j++)
{if(hero[j]>hero[j+1])
{M=hero[j];
hero[j]=hero[j+1];
hero[j+1]=M;
}
}
}
//从小到大遍历龙头和勇士数组,只要符合“勇士的身高不小于龙头的直径”,就把勇士的身高加到score里;
int count = n;
for(j=0;j<m;j++)
{
for(i=0;i<n;i++)
{
if(dragon_head[i] != -1 && hero[j] != -1 && hero[j] >= dragon_head[i])
{
score+= hero[j];
dragon_head[i] = -1; //赋值为-1,表示龙[i]已被杀死;
count--; //用于计数,以其值是否大于零来最后判断bit是否doom;
hero[j] = -1; //赋值为-1,表示勇士[j]已经杀过龙;
}
}
}
if(count > 0)
printf("bit is doomed!\n");
else
printf("%d\n", score);
return 0;
}
3.2简述思路
采用气泡法分别对两个数组中的数进行从小到大排序:
本题的核心是比较勇士的身高和龙头的直径,相当于两个数组中的数进行大小比较;既然要进行两组数的大小比较,那最好的方式当然是先对这两个数组中的数先按大小排序,再将两组数中的数依次比较。
从小到大是因为要保证给出的学分最少,就让身高矮的勇士先冲( 真是坑爹的校长
对两个数组中的数进行大小比较用遍历的方法(双循环实现):
结合代码理解(以n=2,m=3,龙头直径:6,9,勇士身高:7,8,9为例):

为何赋值-1的细节见图中解释。
用计数法来做个例判断:
count用于计数,以其值是否大于零来最后判断bit是否doom。