2020-12-26冒泡排序


# 前言

本文主要介绍冒泡排序算法的原理、实现过程、算法复杂度分析优化及总结。


一、冒泡排序的原理

冒泡排序基本思想是比较相邻的两组记录,以升序为例,如果后面记录比前面记录小则交换,直到遍历到数组第一个元素为止,每趟遍历找到数组中最小的元素,与数组第一个元素交换

二、编程实现及算法分析优化

1.编程实现

以数组a[n]为例(升序),排序步骤为:
1、定义一个数组下标i( 0 <= i < n-1),遍历数组元素用于交换
2、定义另一个数组下标j,j从末尾元素n-1往前遍历比较
3、每找到前面元素 arr[j-1] 比当前位置元素arr[j]大就两两交换

以leetcode第215题,寻找数组第k个最大元素为例 代码如下:
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)


总结

以上就是冒泡排序所有内容,本文对冒泡排序从原理、实现方法、算法分析优化进行总结。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值