一 冒泡排序
冒泡排序算法需要白努力几次数组,在每次遍历中,比较连续相邻的元素,如果某一对元素是降序的,就对换它们的位置。否则保持不变。由于较小的值像“气泡”一样浮向顶部,而较大的值沉向底部,所以称这种技术为冒泡排序法。 或下沉排序法。
使用冒泡排序发,第一次遍历之后 最大的元素排在最后的位置,第二次遍历 第二大的元素排倒数第二的位置,第三次,倒数第三大的值排在倒数第三的位置。一次类推。
如上图所示(5个元素)的排序情况,第一次比较,由于 2< 9 所以不需要 兑换, 从第2 次比较到第四次 9从 一直下沉到最后一个位置,经过第一次遍历后,9 被放到了末尾,
第二次遍历与第一次遍历一样,将 5 放到了 8的前面,由于 8本身小于9 所以不需要对换,此时发现,数组已经排序成功。
算法实现
public static void bubbleSort(int[] args){ for(int i=0 ; i<args.length ; i++){ for(int j =0 ;j<args.length-i-1 ; j++){ if( args[j]>args[j+1]){ int temp = args[j]; args[j]=args[j+1]; args[j+1]=temp; } } } }
注意,如果末次遍历中没有发生交换,那么就不必进行下一次 遍历了,因为所有的元素都已经排号顺序了。,使用这个特点,可以改造以上算法。只要在遍历中发生了一次对换,就说明需要下一次遍历,如果没有 就证明已经牌号顺序了,这可以大大提高 算法的平均效率。
public static void bubbleSort(int[] args){ boolean nextPassNeed = true; for(int i=0 ; i<args.length && nextPassNeed; i++){ nextPassNeed = false; for(int j =0 ;j<args.length-i-1 ; j++){ if( args[j]>args[j+1]){ int temp = args[j]; args[j]=args[j+1]; args[j+1]=temp; nextPassNeed=true; } } } }
性能分析
时间复杂度是 算法计算时间 对于 输入规模的函数,旨在表现 输入规模增加时,算法执行完毕并得出正确结果 的时间的变化曲线 使用O表示。
1 最好的情况:
对于排序来说最好的情况肯定是 对一个已经排号顺序的数组进行排序,在这种情况下,很显然以上算法只需要执行一次遍历即可,因此时间复杂度为O(n);
2最差的情况下:
根据冒泡排序算法,我门不难发现: 对n个元素进行排序时
第一次遍历 需要 n- 次常量计算
第二次 遍历 需要 n-2 次常量计算
第三次遍历 需要 n-3次常量计算
。。。。。。
第n-2 次遍历 需要 2次常量计算
第n-1 次遍历 需要 1 次常量计算
第 n 次 遍历 需要 0 次常量计算
设常量计算次数为K
K = (n-1) + (n-2)+(n-3)+(n-4)+ .... + 3+2+1;
= (n-1)*n / 2
= O(n*n)
总体上来说,冒泡排序发 随着 输入规模的增长,其所用的时间是成 输入规模的平方增长的。 下面程序 用来测试,当输入数组的长度增加十倍时,所用的时间基本在 80-100倍之间。 到100000规模已经能明显感觉到排序的效率在显著降低,到 1 000 000 规模 已经不可忍受,没有进行测试。
public class Algorithm { public static void main(String[] args) { System.out.println("++++++++++++++++++++"); List<Integer> list = new ArrayList<Integer>(); int[] array = new int[10000]; for(int k =0 ; k<10000;k++){ array[k] = (int)(Math.random() * 1000000); } long starttime = System.currentTimeMillis(); bubbleSort(array); System.out.println(System.currentTimeMillis()-starttime); System.exit(0); } public static void bubbleSort(int[] args){ boolean nextPassNeed = true; for(int i=0 ; i<args.length && nextPassNeed; i++){ nextPassNeed = false; for(int j =0 ;j<args.length-i-1 ; j++){ if( args[j]>args[j+1]){ int temp = args[j]; args[j]=args[j+1]; args[j+1]=temp; nextPassNeed=true; } } } } }