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

来源:互联网 发布:手机文字排版软件 编辑:程序博客网 时间:2024/05/21 09:23

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

排序算法有很多,也是各大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)。

0 0
原创粉丝点击