您的位置:首页 > 职场人生

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

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

排序算法有很多,也是各大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)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息