【交换排序】冒泡排序
2015-12-15 18:01
260 查看
冒泡排序(Bubble Sort)
冒泡排序是基于交换排序的一种排序,交换排序的基本思想,是两两比较待排序记录的关键字,一旦发现两个记录不满足次序要求时则进行交换,直到整个序列全部满足要求为止。冒泡排序是一种最简单的交换排序方法,它通过两两比较相邻记录的关键字,如果发生逆序,则进行交换,从而使关键字小的记录如气泡一般逐渐往上“漂浮”(左移),或者使关键字大的记录如石块一样逐渐向下“坠落”(右移)。
[算法思想]
1)设待排序的记录存放在数组r[1..n]中。首先将第一个记录的关键字和第一个记录的关键字进行比较,若为逆序,即r[1]>r[2],则交换两个记录。然后比较第二个记录和第三个记录的关键字。依次类推,直到第n-1个记录和第n个记录的关键字进行过比较为止。上述过程称为第一趟起泡排序,其结果使得关键字最大的记录被安置到最后一个记录的位置上。
2)然后进行第二趟起泡排序,对前n-1个记录进行同样操作,其结果是使得关键字次大的记录被安置到第n-1个记录的位置上。
3)重复上述比较和交换过程,第i趟是从r[1]到r[n-i+1]依次比较相邻两个记录的关键字,并在“逆序”时交换相邻记录,其结果是这n-i+1个记录中关键字最大的记录被交换到第n-i+1的位置上。直到某一趟排序过程中没有进行交换记录的操作,说明序列已全部达到排序要求,则完成排序。
例 已知待排序记录的关键字序列为{70,30,40,10,80,20,90,100,75,60,45},请给出用冒泡排序法进行排序的过程。
待排序的记录共有11个,但算法在第七趟排序过程中没有进行交换记录的操作,则完成排序。
[算法描述]
1.时间复杂度
最好情况(初始序列为正序):只需进行一趟排序,在排序过程中进行n-1次关键字减的比较,且不移动记录;
最坏情况(初始序列为逆序):需进行n-1趟排序,总的关键字比较次数KCN和记录移动次数RMN(每次交换都要移动3次记录)分别为 KCN=n(n-1)/2=(n^2)/2 RMN=3n(n-1)/2=3(n^2)/2
所以在平均情况下,冒泡排序关键字的比较次数和记录移动次数分别约为(n^2)/4和3(n^2)/4,时间复杂度为O(n^2)。
2.空间复杂度
冒泡排序只有在两个记录交换位置时需要一个辅助空间用做暂存记录,所以空间复杂度为O(1)。
[算法特点]
1)是稳点排序。
2)可用于链式存储结构。
3)移动记录次数较多,算法平均时间性能比直接插入排序差。当初始记录无序,n较大时,此算法不宜采用。
[完整代码]
附:<啊哈!算法>冒泡排序的实现
冒泡排序是基于交换排序的一种排序,交换排序的基本思想,是两两比较待排序记录的关键字,一旦发现两个记录不满足次序要求时则进行交换,直到整个序列全部满足要求为止。冒泡排序是一种最简单的交换排序方法,它通过两两比较相邻记录的关键字,如果发生逆序,则进行交换,从而使关键字小的记录如气泡一般逐渐往上“漂浮”(左移),或者使关键字大的记录如石块一样逐渐向下“坠落”(右移)。
[算法思想]
1)设待排序的记录存放在数组r[1..n]中。首先将第一个记录的关键字和第一个记录的关键字进行比较,若为逆序,即r[1]>r[2],则交换两个记录。然后比较第二个记录和第三个记录的关键字。依次类推,直到第n-1个记录和第n个记录的关键字进行过比较为止。上述过程称为第一趟起泡排序,其结果使得关键字最大的记录被安置到最后一个记录的位置上。
2)然后进行第二趟起泡排序,对前n-1个记录进行同样操作,其结果是使得关键字次大的记录被安置到第n-1个记录的位置上。
3)重复上述比较和交换过程,第i趟是从r[1]到r[n-i+1]依次比较相邻两个记录的关键字,并在“逆序”时交换相邻记录,其结果是这n-i+1个记录中关键字最大的记录被交换到第n-i+1的位置上。直到某一趟排序过程中没有进行交换记录的操作,说明序列已全部达到排序要求,则完成排序。
例 已知待排序记录的关键字序列为{70,30,40,10,80,20,90,100,75,60,45},请给出用冒泡排序法进行排序的过程。
待排序的记录共有11个,但算法在第七趟排序过程中没有进行交换记录的操作,则完成排序。
[算法描述]
void BubbleSort(int r[],int Length) { /* 对顺序表r做冒泡排序 */ int m = Length-1;int flag = 1;/* flag用来标志某一趟排序是否发生交换 */ while((m > 0)&&(flag == 1)) { flag=0; /*flag置为0,如果本趟排序没有发生交换,则不会执行下一趟排序*/ for(int j = 1;j< m;j++) { if(r[j]>r[j+1]) { flag=1; /* flag置为1,表示本趟排序发生了交换 */ /* 交换前后两个记录 */ int t=r[j]; r[j]=r[j+1]; r[j+1]=t; } } --m; } }[算法分析]
1.时间复杂度
最好情况(初始序列为正序):只需进行一趟排序,在排序过程中进行n-1次关键字减的比较,且不移动记录;
最坏情况(初始序列为逆序):需进行n-1趟排序,总的关键字比较次数KCN和记录移动次数RMN(每次交换都要移动3次记录)分别为 KCN=n(n-1)/2=(n^2)/2 RMN=3n(n-1)/2=3(n^2)/2
所以在平均情况下,冒泡排序关键字的比较次数和记录移动次数分别约为(n^2)/4和3(n^2)/4,时间复杂度为O(n^2)。
2.空间复杂度
冒泡排序只有在两个记录交换位置时需要一个辅助空间用做暂存记录,所以空间复杂度为O(1)。
[算法特点]
1)是稳点排序。
2)可用于链式存储结构。
3)移动记录次数较多,算法平均时间性能比直接插入排序差。当初始记录无序,n较大时,此算法不宜采用。
[完整代码]
#include<iostream>[运行结果]
using namespace std;
void BubbleSort(int r[],int Length) { /* 对顺序表r做冒泡排序 */ int m = Length-1;int flag = 1;/* flag用来标志某一趟排序是否发生交换 */ while((m > 0)&&(flag == 1)) { flag=0; /*flag置为0,如果本趟排序没有发生交换,则不会执行下一趟排序*/ for(int j = 1;j< m;j++) { if(r[j]>r[j+1]) { flag=1; /* flag置为1,表示本趟排序发生了交换 */ /* 交换前后两个记录 */ int t=r[j]; r[j]=r[j+1]; r[j+1]=t; } } --m; } }
int main()
{
int a[12]={0,70,30,40,10,80,20,90,100,75,60,45}; /* 从a[1]开始 */
BubbleSort(a,12);
for(int i=1;i<12;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
return 0;
}
附:<啊哈!算法>冒泡排序的实现
#include<stdio.h> int main() { int a[101],n,i,j,t; scanf_s("%d",&n); for(i=1;i<=n;i++) { scanf_s("%d",&a[i]); } //开始冒泡排序 for(i=1;i<=n-1;i++) { for(j=1;j<n-i;j++) { if(a[j]>a[j+1]) { t=a[j]; a[j]=a[j+1]; a[j+1]=t; } } } printf("%d ",a[1]); for(i=2;i<=n;i++) { if(a[i]!=a[i-1]) //去重 { printf("%d ",a[i]); } } return 0; }
相关文章推荐
- VS2013编写嵌入网页的ATL控件2-给ATL控件添加鼠标响应
- 如何在移动广告平台中IOS应用中集成插页式广告
- 老李分享:《Linux Shell脚本攻略》 要点(四)
- 中断向量重定位
- 冒泡排序优化
- 请乘坐switch、if和while的时光机
- Android NDK开发之数组类型的操作
- ios9开发之UIAlertController
- tabbar阴影线问题
- ASCII码表
- spring学习单词
- 蓝桥杯 回文数(穷举)
- 链表
- Git远程操作详解
- REFrostedViewController抽屉
- 面试人员的几个方面的问题
- Byte、KB、MB、GB、TB、PB、EB是啥以及它们之间的进率
- 刷新实现原理
- PHP登入网站抓取并且抓取数据
- Oracle客户端使用sqlldr导数据中文乱码问题解决方法