# 前言
本文主要介绍冒泡排序算法的原理、实现过程、算法复杂度分析优化及总结。
一、冒泡排序的原理
冒泡排序基本思想是比较相邻的两组记录,以升序为例,如果后面记录比前面记录小则交换,直到遍历到数组第一个元素为止,每趟遍历找到数组中最小的元素,与数组第一个元素交换
二、编程实现及算法分析优化
1.编程实现
以数组a[n]为例(升序),排序步骤为:
1、定义一个数组下标i( 0 <= i < n-1),遍历数组元素用于交换
2、定义另一个数组下标j,j从末尾元素n-1往前遍历比较
3、每找到前面元素 arr[j-1] 比当前位置元素arr[j]大就两两交换
void swap(int *a, int *b);//元素交换
int findKthLargest(int*arr, int len, int k){
//冒泡排序过程(升序)
//1、定义一个数组下标i(0 <= i < len-1),遍历数组用于交换
//2、定义另一个数组下标j,j从末尾元素len-1往前遍历两两比较
int i, j;
for(i = 0; i < len - 1 ; i++){
for(j = len - 1; j > i; j--){
//3、元素 arr[j-1] 比当前位置元素arr[j]大就交换
if(arr[j] < arr[j - 1])
swap(&arr[j], &arr[i]);
}
}
return arr[len - k];//返回排序后的第k个最大元素
}
void swap(int *a, int *b){
int tmp ;
tmp = *a;
*a = *b;
*b = tmp;
}
2.算法分析及优化思路
由于内层循环(j从len - 1到 i),i = 0 ,执行len - 1次;i = 1,执行len - 2次,所以总执行次数为1 加到len - 1次,故时间复杂度T(n) = (1+ n-1)n/2= 1/2 *n^2,
时间复杂度为O(n^2)
对于部分有序的待排序列,例如arr = [3, 2, 5, 7, 8, 9, 12], 一趟排序后数列就有序了,但是冒泡排序仍然在内层循环两两比较,会消耗不必要的比较时间,所以优化思路是当一趟排序没有两两交换后,说明数组有序了,优化做法是采用标志flag来判断是否有序
代码如下
void swap(int *a, int *b);//元素交换
int findKthLargest(int*arr, int len, int k){
//冒泡排序过程(升序)
//1、定义一个数组下标i(0 <= i < len-1),遍历数组用于交换
//2、定义另一个数组下标j,j从末尾元素len-1往前遍历两两比较
int flag = 1//定义一个标记
int i, j;
for(i = 0; i < len - 1 && flag == 1 ; i++){//只有当标记为1,也就是有交换才进行
flag = 0;//初始化标记
for(j = len - 1; j > i; j--){
//3、元素 arr[j-1] 比当前位置元素arr[j]大就交换
if(arr[j] < arr[j - 1]){
swap(&arr[j], &arr[i]);
flag = 1;//当有交换则将标记置1
}
}
}
return arr[len - k];//返回排序后的第k个最大元素
}
void swap(int *a, int *b){
int tmp ;
tmp = *a;
*a = *b;
*b = tmp;
}
优化之后排序最好的情况(有序)时间复杂度为O(n),最坏的情况仍为O(n^2)