基本思想:
在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。
算法实现:(HDU 1040 亲测 AC)
#include<iostream> using namespace std; const int N =1005; void BubbleSort(int a[],int ); void print(int a[],int num); void swap(int &a,int &b); int main() { int s[N]; int T; cin>>T; while(T--) { int n; cin>>n; for(int j=0;j<n;j++) cin>>s[j]; BubbleSort(s,n); print(s,n); cout<<endl; } return 0; } void BubbleSort(int a[],int num)//冒泡排序算法 { for(int i=0;i<num-1;i++) { for(int j=0;j<num-i-1;j++) { if(a[j]>a[j+1]) { swap(a[j],a[j+1]); } } } } void swap(int &a,int& b)//交换元素 { int temp; temp=a; a=b; b=temp; } void print(int a[],int n)//输出数组元素 { cout<<a[0]; for(int k=1;k<n;k++) { cout<<" "<<a[k]; } }
n个数排序 比较趟数为n-1次
算法时间复杂度:O(n2)
空间复杂度 :O(n)
改进版本:
上面的冒泡排序中每一趟排序操作只能找到一个最大值或最小值,但如果在每趟排序中进行正向和反向两遍冒泡的方法一次可以得到两个最值(最大者和最小者) , 从而使排序趟数几乎减少了一半。
void BubbleSort_Modify(int a[],int num)//冒泡排序算法 { int low=0; int high=num-1; while(low<high) { for(int i=low;i<high;i++)// 正向冒泡得到最大值 if(a[i]>a[i+1]) swap(a[i],a[i+1]); high--;//high前移一位 for(int i=high;i>low;i--)// 反向冒泡得到最小值 { if(a[i]<a[i-1]) swap(a[i],a[i-1]); } low++;//low后移一位 } }
优化二:
若在某一趟排序中未发现气泡位置的交换,则说明待排序的无序区中所有气泡均满足轻者在上,重者在下的原则,因此,冒泡排序过程可在此趟排序后终止。为此,在下面给出的算法中,引入一个标签flag,在每趟排序开始前,先将其置为0。若排序过程中发生了交换,则将其置为1。各趟排序结束时检查flag,若未曾发生过交换则终止算法,不再进行下一趟排序。
void BubbleSort2(int a[],int n) { int i=0,j=0; for(i=0;i<n-1;i++) { int flag=0; for(j=0;j<n-i-1;j++) { if(a[j]>a[j+1]) { int tmp=a[j]; a[j]=a[j+1]; a[j+1]=tmp; flag=1; } }
//判断标志位是否为0,如果为0,说明后面的元素已经有序,就直接return if(flag==0) return; } }