参考:《啊哈算法》《C语言进阶:重点、难点与疑点解析》
1.推导过程
最后我们总结一下:如果有 n 个数进行排序,只需将 n-1 个数归位,也就是说要进行
n-1 趟操作。而“每一趟”都需要从第 1 位开始进行相邻两个数的比较,将较小的一个数放在后面,比较完毕后向后挪一位继续比较下面两个相邻数的大小,重复此步骤,直到最后一个尚未归位的数,已经归位的数则无需再进行比较(已经归位的数你还比较个啥,浪费表情。
2.核心思想
冒泡排序的基本思想是:每次比较两个相邻的元素,如果它们的顺序错误就把它们交换过来。
“冒泡排序”的原理是:每一趟只能确定将一个数归位。如果是降序排列,那么越小的越靠后
3.eg
任意输入<100以内的数字,升序排列
#include<stdlib.h>
#include<stdio.h>
int main()
{
int data[100];
int num;
int t;
scanf("%d",&num);
for(int i=1;i<=num;i++)
scanf("&d",&data[i]);
//冒泡核心
for(int i=1;i<=num-1;i++)
for(int j=1;j<=n-i;j++)//想一想为什么到n-i就可以了?把i=1去理解一下,再把j=n-i带入下面的if语句去理解下
if(data[j]>data[j+1])
t=data[j];
data[j]=data[j+1];
data[j+1]=t;
for(int i=1;i<=num;i++)
printf("%d",data[i]);
return 0;
}
验证:
输入:
10
8 100 50 22 15 6 1 1000 999 0
输出:
0 1 6 8 15 22 50 100 999 1000
4.时间复杂度
N:待排序的个数
so,时间复杂度=O(N^2)
5.补充的eg
如果输入的是下面的这种数据。并按照字符串后面的数字降序排列,然后输出前面的字符串,该怎么办呢?
输入:
5
huhu 5
haha 3
xixi 5
hengheng 2
gaoshou 8
输出:
gaoshou
huhu
xixi
haha
hengheng
#include<stdlib.h>
#include<stdlib.h>
int main()
{
struct student
{
int score;
char str[100];
};
int num;
scanf("%d",&num);
int data[100];
for(int i=1;i<=num;i++)
scanf("%s %d",&data[i].str,&data[i].score);
//冒泡核心
int t;
for(int i=1;i<=num-1;i++)
for(int j=1;j<=num-i;j++)
if(data[j].score<data[j+1].score)
t=data[j].score;
data[j].score=data[j+1].score;
data[j+1].score=t;
for(int i=1;i<=num;i++)
printf("%s\n",a[i].str);
return 0;
}
6.改进的冒泡排序
为了防止对已经完成排序功能的数据进行没有任何意义的比较操作
解决的基本思想是:
int bubble(int b[],int n)
{
int flag;
int t;
for(int i=0;i<n;i++)
flag=1;
for(int j=0;j<n-i-1;j++)
if(b[j]>b[j+1])
{
t=b[j];
b[j]=b[j+1];
b[j+1]=t;
flag=0;
}
if(1==flag)
break;
printf("比较的次数为:%d",i+1);
return;
}
int main()
{
int a[]={12,54,25,54,85,45}
bubble(a,5);
for(int i=0;i<5;i++)
printf("%d",a[i]);
return 0;
}