算法定义:
冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。
它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。
这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。
算法分析:
时间复杂度
若文件的初始状态是正序的,一趟扫描即可完成排序。所需的关键字比较次数和记录移动次数均达到最小值:
。
所以,冒泡排序最好的时间复杂度为
。
若初始文件是反序的,需要进行
趟排序。每趟排序要进行
次关键字的比较(1≤i≤n-1),且每次比较都必须移动记录三次来达到交换记录位置。在这种情况下,比较和移动次数均达到最大值: 冒泡排序的最坏时间复杂度为
。
综上,因此冒泡排序总的平均时间复杂度为
。
算法稳定性
冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,是不会再交换的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。
C代码
bubble_sort.c
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <time.h> 4 #include <string.h> 5 #include <sys/time.h> 6 7 #include "common.h" 8 9 struct ArrayData 10 { 11 int iLen; 12 int Array[0]; 13 }; 14 15 void swap(int *a, int *b) 16 { 17 int iTmp; 18 iTmp = *a; 19 *a = *b; 20 *b = iTmp; 21 } 22 23 void bubble_sort(int *iArray, int len) 24 { 25 for(int index = 0; index < len - 1; index++) 26 { 27 for(int j = 0; j < len-1-index; j++) 28 { 29 if(iArray[j] > iArray[j+1]) 30 { 31 swap(&iArray[j], &iArray[j+1]); 32 } 33 } 34 } 35 } 36 37 int main(int argc, char **argv) 38 { 39 //int iArray[10000] = {0}; 40 int size = atoi(argv[1]); 41 struct ArrayData *iArrayData = NULL; 42 struct timeval stTimeStart; 43 iArrayData = malloc(sizeof(struct ArrayData) + size * sizeof(int)); 44 iArrayData->iLen = size; 45 int *iArray = iArrayData->Array; 46 unsigned long ulTimeUse = 0; 47 48 memset(&stTimeStart, 0, sizeof(stTimeStart)); 49 50 /* 初始化随机数发生器 */ 51 srand((unsigned)time(NULL)); 52 53 for(int i = 0; i < size; i++) 54 { 55 iArray[i] = rand() % 200 - 100; 56 } 57 58 //printf("冒泡排序前: "); 59 //for(int i = 0; i < size; i++) 60 //{ 61 //printf("%d ", iArray[i]); 62 //} 63 64 COMMON_StartRecordTime(&stTimeStart); 65 bubble_sort(iArray, size); 66 ulTimeUse = COMMON_EndRecordTime(&stTimeStart); 67 68 printf("排序%d个数据,耗时%ld usec. ", size, ulTimeUse); 69 //printf(" 冒泡排序后: "); 70 //for(int i = 0; i < size; i++) 71 // { 72 // printf("%d ", iArray[i]); 73 //} 74 //printf(" "); 75 76 return 1; 77 }
common.c
1 #include <stdio.h> 2 #include <sys/time.h> 3 4 void COMMON_StartRecordTime(struct timeval *pstTimeStart) 5 { 6 gettimeofday(pstTimeStart, NULL); 7 } 8 9 unsigned long COMMON_EndRecordTime(struct timeval *pstTimeStart) 10 { 11 struct timeval stTimeEnd; 12 gettimeofday(&stTimeEnd, NULL); 13 return 1000000 * (stTimeEnd.tv_sec - pstTimeStart->tv_sec) + (stTimeEnd.tv_usec - pstTimeStart->tv_usec); 14 }
comman.h
1 extern void COMMON_StartRecordTime(struct timeval *pstTimeStart); 2 extern unsigned long COMMON_EndRecordTime(struct timeval *pstTimeStart);