冒泡排序算法-图解
冒泡排序的形象意义:
将被排序的记录数组R[1..n]垂直排列,每个记录R[i]看作是重量为R[i].key的气泡。根据轻气泡不能在重气泡之下的原则,从下往上扫描数组R:凡扫描到违反本原则的轻气泡,就使其向上"飘浮"。
如此反复进行,直到最后任何两个气泡都是轻者在上,重者在下为止。
import java.util.Scanner; public class BubbledSort{ public static void BubbledSort(int[] inArrary) { int tmp = 0; for(int i=1;i<inArrary.length;i++){//两层循环 for(int j=0;j<inArrary.length-i;j++){ if(inArrary[j]<inArrary[j+1]){//从大到小 tmp = inArrary[j+1]; inArrary[j+1] = inArrary[j]; inArrary[j] = tmp; } } } for(int x = 0;x<inArrary.length;x++){//数组的length方法,没有括号。String的length方法有括号。 System.out.println(inArrary[x]); } } public static void main(String[] args){ Scanner sc = new Scanner(System.in); while(sc.hasNext()){ String[] strArrary = sc.nextLine().split(","); //String的split()方法,传入分隔符字符串"," 返回String[]。有些间隔符需要转义 int[] intArrary = new int[strArrary.length];//数组定义时需要声明大小 for(int i = 0;i<strArrary.length;i++){ intArrary[i] = Integer.valueOf(strArrary[i]);//Integer.valueOf(),传入String[],返回int[] } BubbledSort(intArrary); } } }
交换图解:按逆时针方向生成赋值语句,分3步实现a[j]和a[j+1]的值交换(注意顺序)
外层循环:
第一次外层循环将整个数组中最大值,交换到队尾;
第二次外层循环将整个数组中第二大值,交换到倒数第二位,由上一次循环可知此时队尾的值是最大值;
第(a.length-1)次外层循环将整个数组中第第二小值,交换到第二位脚标位,此时排序完成。
内层循环:
第一次内层循环比较0,1号脚标位上的数值大小,将二者按从小到大交换;
第二次内层循环比较1,2号脚标位上的数值大小,将二者按从小到大交换;
第a.length-2次内层循环比较a.length-2,a.length-1号脚标位上的数值大小,将二者按从小到大交换;
这样下来就能将整个队列的最大值,交换到队尾。
下面为内存循环图解:
时间复杂度:
这个时间复杂度还是很好计算的:外循环和内循环以及判断和交换元素的时间开销;
最优的情况也就是开始就已经排序好序了,那么就可以不用交换元素了,则时间花销为:[ n(n-1) ] / 2;所以最优的情况时间复杂度为:O( n^2 );
最差的情况也就是开始的时候元素是逆序的,那么每一次排序都要交换两个元素,则时间花销为:[ 3n(n-1) ] / 2;(其中比上面最优的情况所花的时间就是在于交换元素的三个步骤);所以最差的情况下时间复杂度为:O( n^2 );
综上所述:
最优的时间复杂度为:O( n^2 ) ;有的说 O(n),下面会分析这种情况;
最差的时间复杂度为:O( n^2 );
平均的时间复杂度为:O( n^2 );
空间复杂度:
空间复杂度就是在交换元素时那个临时变量所占的内存空间;
最优的空间复杂度就是开始元素顺序已经排好了,则空间复杂度为:0;
最差的空间复杂度就是开始元素逆序排序了,则空间复杂度为:O(n);
平均的空间复杂度为:O(1)。
更形象易懂的理解请参链接内容:http://www.cnblogs.com/gansc23/archive/2010/12/15/1859981.html,其中
有序区/无序区的概念,让循环过程中数组的状态变得更清晰;
交换标志让排序过程张开了眼睛,运气够好,顺序排列较多的情况,能以更少循环次数结束排序工作。