排序算法:冒泡排序
主要参考书籍《信息学奥赛一本通》(董永建)
目录
基本思想
每一次排序将数据元素(数组为例)通过两两比较关键字,得出升序序列或者降序序列。
举个栗子
以无序数组[7 5 6 1]为例,第一次起泡过程如下:
7 5 6 1--5 7 6 1--5 6 7 1--5 6 1 7
在这里7被固定下来
第二次起泡如下:
5 6 1 7--5 6 1 7--5 1 6 7
在这里6被固定下来
第三次起泡如下
5 1 6 7--1 5 6 7
5被固定下来,至此起泡结束(其过程与泡泡从水底浮至水面有点相像,,,)
实现方法
外层循环i控制每轮要进行多少次比较,第1轮比较n-1次,第2轮比较n-2次,...最后1轮比较1次;
内层循环j控制每轮i次比较的相邻的两个元素顺序是否颠倒,若颠倒就交换两个元素。
代码示例
#include<iostream>
using namespace std;
const int MAXN = 10001;
int main()
{
int n,i,j;
float temp,a[MAXN];
cin>>n;
for(i=1;i<=n;i++)
cin>>a[i];
for(i=n;i>1;i--)//进行n-1次冒泡
{
for(j=1;j<i;j++) //每轮进行i次比较
{
if(a[j]>a[j+1])
swap(a[j],a[j+1]);//交换
}
}
for(i=1;i<=n;i++)
cout<<a[i]<<""<<endl;
system("Pause\n");
return 0;
}
效果展示
![](https://i-blog.csdnimg.cn/blog_migrate/f9f067383e86237e02a68976ddc98b1c.png)
优化
对于有些数据,我们不难发现不一定要n-1次才能排序完成,比如1 5 2 3,只需要一次排序就可以了。
我们不妨设置一个布尔变量,判断是否有进行交换,从而减少排序次数。
#include<iostream>
using namespace std;
const int MAXN = 10001;
int main()
{
int n,i,j;
float temp,a[MAXN];
cin>>n;
for(i=1;i<=n;i++)
cin>>a[i];
bool ok;
for(int i=n;i>1;i--)
{
ok=true;
for(int j=1;j<i;j++)
{
if(a[j]>a[j+1])
{
awap(a[j],a[j+1]);
ok=false;
}
}
if(ok==true)break;
}
for(i=1;i<=n;i++)
cout<<a[i]<<""<<endl;
system("Pause\n");
return 0;
}
习题_车厢重组
车厢有标号1 2 3 4....现今将车厢顺序打乱,每次调换顺序只能相邻两节车厢进行调换,问最少的调换次数。
#include<iostream>
#include<cstdio>
using namespace std;
long n,i,j,t,s,a[10000];
int main()
{
cin>>n;
for(i=1;i<=n;i++)
cin>>a[i];
for(i=1;i<=n-1;i++)
for(j=1;j<=n-1;j++)
if(a[j]>a[j+1])
{
swap(a[j],a[j+1]);
s++;
}
for(i=1;i<=n;i++)
cout<<"-"<<a[i]<<"-"<<endl;
cout<<s<<endl;
system("Pause\n");
return 0;
}
答案示例:
4
8 7 6 5
-5-
-6-
-7-
-8-
6