冒泡排序
原理:从左到右,相邻元素进行比较。每次比较一轮,就会找到序列中最大的一个或最小的一个。这个数就会从序列的最右边冒出来。
以从小到大排序为例,第一轮比较后,所有数中最大的那个数就会浮到最右边;第二轮比较后,所有数中第二大的那个数就会浮到倒数第二个位置……就这样一轮一轮地比较,最后实现从小到大的排序。
函数代码如下:
void Bubble_sort(int a[], int size)
{
int j,i,tem;
for (i = 0; i < size-1;i ++)//size-1是因为不用与自己比较,所以比的数就少一个
{
int count = 0;
for (j = 0; j < size-1 - i; j++) //size-1-i是因为每一趟就会少一个数比较
{
if (a[j] > a[j+1])//这是升序排法,前一个数和后一个数比较,如果前数大则与后一个数换位置
{
tem = a[j];
a[j] = a[j+1];
a[j+1] = tem;
count = 1;
}
}
if (count == 0) //如果某一趟没有交换位置,则说明已经排好序,直接退出循环
break;
}
}
利用冒泡排序能否解决洛谷排序
【排序 入门】https://www.luogu.com.cn/problem/P1177
代码如下:
# include <stdio.h>
void Bubble_sort(int a[], int n)
{
int j,i,tem;
for (i = 0; i < n-1;i ++)
{
int count = 0;
for (j = 0; j < n-1 - i; j++)
{
if (a[j] > a[j+1])
{
tem = a[j];
a[j] = a[j+1];
a[j+1] = tem;
count = 1;
}
}
if (count == 0)
break;
}
}
int main () {
int n;
scanf("%d",&n);
int a[n];
int i;
int x;
for(i=0;i<n;i++){
scanf("%d",&x);
a[i]=x;
}
Bubble_sort(a, n);
for (i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
return 0;
}
超出时间限制
虽然输入这段代码在DevC++里可以运行且结果正确,但是洛谷却会出现Time Limit Exceeded.(超出时间限制)
问题出在哪里呢?
以上冒泡排序为朴素冒泡,可知稳定计算n^2次,超出洛谷对时间的限制要求。那么我们能不能利用分治思想来解决呢?
分而治之行不行?
代码如下:
# include <stdio.h>
void Bubble_sort(int a[], int n)
{
int j,i,tem;
for (i = 0; i < n-1;i ++)
{
int count = 0;
for (j = 0; j < n-1 - i; j++)
{
if (a[j] > a[j+1])
{
tem = a[j];
a[j] = a[j+1];
a[j+1] = tem;
count = 1;
}
}
if (count == 0)
break;
}
}
int main () {
int n;
scanf("%d",&n);
int a[n];
int i;
int x;
for(i=0;i<n;i++){
scanf("%d",&x);
a[i]=x;
}
int b[n];
int c[n];
int d[n];
int j=0;
int k=0;
int l=0;
for(i=0;i<n;i++){
if(a[i]>a[n/2]){
b[j]=a[i];
j++;
}
else if(a[i]<a[n/2]){
d[l]=a[i];
l++;
}
else{
c[k]=a[i];
k++;
}
}
int f=l;
int s=j;
int y=k;
Bubble_sort(b, s);
Bubble_sort(d, f);
for(l=0;l<f;l++){
printf("%d ",d[l]);
}
for(k=0;k<y;k++){
printf("%d ",c[k]);
}
for (j= 0; j < s; j++)
{
printf("%d ", b[j]);
}
return 0;
}
我们已经对冒泡排序进行优化,但是洛谷并没有给出满分。
这是因为优化后,每次只对有序部分进行排序,就是n+n-1+n-2+···+1次,也就是(n^2-n)/2。我们计算时间复杂度的时候,一般只看最高阶,所以还是n的2次方次。因此,无论冒泡排序是否优化都是过不了洛谷的。