一:冒泡排序算法原理
1.比较相邻元素,如果第一个比第二个大,则交换他们(从小到大排序)。
2.对每一对相邻的元素做同样的工作,从开始的一对最后一对,从而最后一个元素必定是最大的。
3.对于所有元素重复以上过程,除了最后一个。
4.进行完每一趟 的比较时,对越来越少的数字进行上述排序,知道最后没有任何一个数字需要比较。
第一趟比较之后:15 48 85 5 19 64 37 3 99.
二:算法描述
#include<iostream>
using namespace std;
template<typename T>
void bubble_sort(T arr[],int len)
{
int count = 0;//用于优化的计数器
T temp = T();
for(int i=0;i<len-1;++i)
{
for(int j=0;j<len-1-i;++j)
{
if(arr[j]>arr[j+1])
{
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
count++;
}
}
if(count == 0)
//当在每一趟的比较中,如果此时数据元素已经有序,
不需要进行数据的交换,那么此时我们可以直接返回,
{
return;
}
else
{
count = 0;
}
}
}
int main()
{
int arr[]={15,48,95,65,3,8,99,18,47};
int len = sizeof(arr)/sizeof(arr[0]);
bubble_sort(arr,len);
for(int i=0;i<len;++i)
{
cout<<arr[i]<<" ";
}
double brr[]={12.3,12.4,15.9,5.5,94.9,14.8,5,67,4.3};
int len1 = sizeof(brr)/sizeof(brr[0]);
bubble_sort(brr,len1);
for(int i=0;i<len;++i)
{
cout<<brr[i]<<" ";
}
cout<<endl;
return 0;
}
三:时间复杂度
若文件的初始状态是正序的,一趟扫描即可完成排序。所需要进行的比较次数为C和记录移动次数M均为最小值
Cmin =n -1,Mmin = 0。
所以冒泡排序的最好的时间复杂度为O(n)。
如果初始文件数据是反序的,需要进行n-1趟排序,每趟排序需要进行n-i次关键字的比较(1<=i<=n-i),且每次比较都记录三次来达到交换记录位置。这种情况下,比较和移动的次数均达到了最大值:
Cmax = n(n-1)/2 = O(n*n)
Mmax = 3n(n-1)/2 = O(n*n) (等差数列求和)
所以冒泡排序的最坏的时间复杂度为O(n*n)
四:算法稳定性
冒泡排序就是把最小的元素往前调或者把最大的元素往后调。比较的是相邻元素比较,交换也发生在两个元素之间,所以,如果两个元素相等,是不会再交换的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,也不会交换,所以相同元素的前后顺序没有改变,所以冒泡排序是一种稳定的排序算法。