每天一算法,每天一小歩——冒泡排序

5 篇文章 0 订阅
5 篇文章 0 订阅

常言道,生活在于积累,学习技术也是如此,每天积累一点,每天一小步,慢慢的便会发现自己走得越来越远,离自己的目标也会越来越近。

排序算法有很多,也是各大IT公司必考的题目。

其中冒泡和快速排序是经常考的,也是最基本的排序算法。

冒泡排序的基本思想是首先每次按顺序扫描一次集合,初始这个集合是无序的,将相邻的元素两两进行比较,若第一个元素比第二个元素大(或者小)则交换位置,直到集合比较完,这个时候,集合中最大(或者最小)的元素便排在集合最后一个位置,我们称之为有序区,这个时候将剩下的元素重新进行一趟排序,得到余下元素中最大的,这样一直循环比较,每趟排序都能找到在无序集合中最大的一个元素,最后位置总是在无序集合的最后一个位置,然后将其归入有序集合中,我们将每个元素都看作一个气泡,每次两两比较之后,最大(或者最小)的气泡总能往后浮,最后最大(或者最小)的气泡总能浮动到无序区中的最后一个位置,就好像冒泡一样,这样每趟排序都使得有序区增加一个气泡,在经过n-1趟排序之后,有序区就增加了n-1个气泡,这样排列完之后,集合变由无序变成了有序。代码如下:

/*	程序来源:排序算法练习
 * 	源文件名称:BubbleSort.java
 *	要  点:
 *		冒泡排序算法
 *		
 */

public class BubbleSort{
	public static void bubbleSort(int[] src){
		int temp = 0;
		for(int i = src.length;i>0;i--){
			for(int j = 0;j<i-1;j++){
				if(src[j]>src[j+1]){
					temp = src[j];
					src[j] = src[j+1];
					src[j+1] = temp;
				}
			}
		}
	}
	
	public static void main(String[] args){
		int[] arr = {2,3,6,8,12,56,1,9,5,23,17,10,43};
		bubbleSort(arr);
		for(int i = 0;i<arr.length;i++){
			System.out.println(arr[i]);
		}
	}
} 


如果说在某一趟排序中,没有产生位置的交换,那么说明原来的元素都是有序的,因此,排序在此趟之后便可以终止。因此,可以进行改进,加入一个boolean类型的变量exchange,一开始为false,如果某趟排序产生了交换,则exchange为true,每趟排序解释检查一遍exchange,如果为false则排序提前结束。具体程序如下:

/*	程序来源:排序算法练习
 * 	源文件名称:BubbleSort.java
 *	要  点:
 *		冒泡排序算法
 *		
 */

public class BubbleSort{
	public static void bubbleSort(int[] src){
		private int index = 0;				//比较计数
		private int temp = 0;
		private boolean exchange;	//交换标志 
		for(int i = src.length;i>0;i--){
			exchange = false;
			for(int j = 0;j<i-1;j++){
				index++;
				if(src[j]>src[j+1]){
					exchange = true;
					temp = src[j];
					src[j] = src[j+1];
					src[j+1] = temp;
				}
			}
			if(!exchange){				//如果本趟排序没有元素交换,则算法提前终止
				System.out.println("compare : "+index+" times");	//输出循环次数
				return;
			}
		}
		System.out.println("compare : "+index+" times");			//输出循环次数
	}
	
	public static void main(String[] args){
		int[] arr = {2,3,6,8,12,56,1,9,5,23,17,10,43};
		int[] arr2 = {1,2,3,4,5,6,7,8,9,10,11,12,13};
		bubbleSort(arr);
		bubbleSort(arr2);
		for(int i = 0;i<arr.length;i++){
			System.out.println(arr[i]);
		}
	}
} 

其中引入index是为了作计数比较,可以看出如果在arr2中,数组一开始就是有序的,所以排序只进行了12次,而arr本来应该进行78次比较,最后只进行了63次。


总结:

1.算法时间复杂度分析

如果集合的初始状态是正序的,那么一趟扫描边可以完成排序,所进行的关键字比较(n-1)和记录移动次数(0)都是最小的,因此最好情况下时间复杂度是O(n),如果初始状态是反序的,那么需要进行n-1趟排序,每次排序进行n-i次关键字比较(1<=i<=n-1),,而且每次比较都必须移动记录,这种情况下,比较和移动次数都达到了最大值,因此时间复杂度是总共比较n-1趟,然后每趟比较n-i次关键字,所以是1+2+...+n-1 = (n-1)(n-1+1)/2 = n(n-1)/2 ,即O(n^2)。所以平均时间复杂度也为O(n^2)。

2.稳定性分析

冒泡算法是就地进行排序,并且对于相同键值的元素,其相对位置在排序时没有发生改变,所以是稳定的排序。

3.空间复杂度分析

由于算法在运行过程中临时占用的存储空间随算法的不同而异,有的算法只需要占用少量的临时工作单元,而且不随问题规模的大小而改变,我们称这种算法是“就地\"进行的,是节省存储的算法,因此冒泡排序过程中占用的临时工作单元不随问题规模大小而改变,因此它是就地进行的,所以空间复杂度为一个常量,即不随被处理数据量n的大小而改变时,可表示为O(1)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值