基本算法研究1-冒泡排序算法测试
1、经典冒泡排序法基本原理
先看一个动态图,感觉比较形象:
冒泡排序(Bubble Sort)是一种简单的排序算法。默认是从小到大排序,即把最大的数据排在最后,相当于每次把最大数据像气泡一样浮到水面一样。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换。
基本步骤:
1、比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2、对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
3、针对所有的元素重复以上的步骤,除了最后一个。
4、持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
最经典的冒泡排序法就是两层For循环嵌套。外层For循环是“趟”数,内层是每一“趟”对相邻的两个数据进行大小比较,根据需要进行交换位置。
int a[SORT_NUM];for (int i=0; i<SORT_NUM; i++)a[i]=arc4random()%SORT_NUM+1;//随机生成数组
for (int i=0; i<SORT_NUM; i++)//外层循环{
for (int j=0; j<SORT_NUM-i-1; j++)//内层循环{
if (a[j]>a[j+1])//交换数据{int temp=a[j];a[j]=a[j+1];a[j+1]=temp;} }}
2、冒泡排序的性能
时间复杂度:平均:O(n²) 最好:O(n²) 最差:O(n²)
稳定:稳定的
空间复杂度:O(1)
备注:在n较小时排序效果比较好,优点是比较简单。但是随着n的增大,耗时增加很快。
3、实际测试结果
使用Xcode对冒泡排序进行了测试,结果如下
n | n倍数 | 第1次 | 第2次 | 第3次 | 平均 | 时间倍数 | 使用时间(单位) |
10 | 18.00 | 25.03 | 14.01 | 19.01 | 微秒 | ||
100 | 10 | 67.97 | 70.99 | 43.99 | 60.98 | 3.21 | 微秒 |
1000 | 10 | 2.07 | 1.94 | 2.08 | 2.03 | 33.29 | 毫秒 |
10 000 | 10 | 298.59 | 265.01 | 279.29 | 280.96 | 138.40 | 毫秒 |
100 000 | 10 | 29.89 | 31.18 | 32.51 | 31.19 | 111.01 | 秒 |
200 000 | 2 | 129.95 | 122.60 | 128.04 | 126.98 | 4.07 | 秒 |
基本上可以发现,随着数据规模增加到之前的N倍,所用的时间是之前所用时间的N²倍。比如一万数据用时是280.96毫秒,十万数据用时是31.19秒,十万数据用时是一万数据用时的111.01倍(大约是10²倍)。和冒泡排序法的时间复杂度O(N²)是相符的。
测试程序如下:
在Xcode下运行。
#import <Foundation/Foundation.h>
#define SORT_NUM 200000 //需要排序的数组的长度
int main(int argc, const char * argv[]) {
#pragma mark --startint a[SORT_NUM];printf("未排序:");for (int i=0; i<SORT_NUM; i++){//随机生成数组a[i]=arc4random()%SORT_NUM+1;// printf(" %d",a[i]);}NSDate * startTime=[NSDate date];startTime=[startTime dateByAddingTimeInterval:60*60*8];for (int i=0; i<SORT_NUM; i++)//外层循环{for (int j=0; j<SORT_NUM-i-1; j++)//内层循环{if (a[j]>a[j+1])//交换数据{int temp=a[j];a[j]=a[j+1];a[j+1]=temp;}}}NSDate * endTime=[NSDate date];endTime=[endTime dateByAddingTimeInterval:60*60*8];NSTimeInterval sortTime=[endTime timeIntervalSinceDate:startTime];printf("\n排序后:\n");//for (int i=0; i<SORT_NUM; i++)// printf(" %d",a[i]);NSLog(@"开始时间:%@",startTime);NSLog(@"结束时间:%@",endTime);NSLog(@"使用时间:%.2f微秒",sortTime*1000000);NSLog(@"使用时间:%.2f毫秒",sortTime*1000);NSLog(@"使用时间:%.2f秒",sortTime);printf("\n冒泡排序\n");#pragma mark --endreturn 0;
}