算法原理:
第一趟:从j=0开始,比较相邻的两个数a[j]和a[j+1],如果a[j]>a[j+1],则交换他俩的位置,这样会将大的数放在后面。每比较一次让j++,当j=length-1时终止。
这样一趟走完,最后面的数应该是最大数。
那么第二趟,还是从0开始,只不过这次j的终止条件是j=length-2。第二趟走完,最后两个数应该是数组中最大的两个数并且有序排列。
重复若干趟,直到j的终止条件是j=0
算法分析:(部分自于百度百科)
时间复杂度
若文件的初始状态是正序的,一趟扫描即可完成排序。所需的关键字比较次数
和记录移动次数
均达到最小值:
,
。
![](https://i-blog.csdnimg.cn/blog_migrate/d0af818aab6ce789bb3bf841d08e77de.png)
![](https://i-blog.csdnimg.cn/blog_migrate/fbd9dc8acc7c15a295765826b59d0bc8.png)
![](https://i-blog.csdnimg.cn/blog_migrate/d2b22088738d34fc5f571056659bcecc.png)
![](https://i-blog.csdnimg.cn/blog_migrate/11c341f1ff963372114b303f4d05f3fd.png)
所以,冒泡排序最好的时间复杂度为
。
若初始文件是反序的,需要进行
趟排序。每趟排序要进行
次关键字的比较(1≤i≤n-1),且每次比较都必须移动记录三次来达到交换记录位置。在这种情况下,比较和移动次数均达到最大值:
![](https://i-blog.csdnimg.cn/blog_migrate/dc15aaddebe0f88faadbdc2a644589e9.png)
若初始文件是反序的,需要进行
![](https://i-blog.csdnimg.cn/blog_migrate/3ac4aaf599bc4dd074f7559041a1de98.png)
![](https://i-blog.csdnimg.cn/blog_migrate/602a091746cb99c3b78894d250baa03b.png)
![](https://i-blog.csdnimg.cn/blog_migrate/98ebdd5685e4ebe53665f0522a70d541.png)
![](https://i-blog.csdnimg.cn/blog_migrate/e330e74e89cccb0209f4597007a0be11.png)
冒泡排序的最坏时间复杂度为
。
综上,因此冒泡排序总的平均时间复杂度为
。
![](https://i-blog.csdnimg.cn/blog_migrate/5d802ef99f4f53fa00d98234740aabe3.png)
![](https://i-blog.csdnimg.cn/blog_migrate/5d802ef99f4f53fa00d98234740aabe3.png)
算法稳定性(相同数据排序后相对位置不变)
冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。
#include "stdafx.h"
#include<iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int a[10]= {9,2,4,1,5,0,6,7,3,8};
for(int i =9;i>0;i--) {
for(int j=0;j<i;j++) {
if(a[j]>=a[j+1]){
int tmp =a[j+1];
a[j+1]=a[j];
a[j]=tmp;
}
}
}
for (int i= 0; i < 10; i++){
cout<<a[i];
}
system("PAUSE");
return 0;
}