本文共 1544 字,大约阅读时间需要 5 分钟。
原理:比较两个相邻的元素,将值大的元素交换至右端。
思路:依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。重复第一趟步骤,直至全部排序完成。
第一趟比较完成后,最后一个数一定是数组中最大的一个数,所以第二趟比较的时候最后一个数不参与比较;
第二趟比较完成后,倒数第二个数也一定是数组中第二大的数,所以第三趟比较的时候最后两个数不参与比较;
依次类推,每一趟比较次数-1;
……出现的问题也来源于两次无脑的循环,正是因为循环不顾一切的向下执行,所以会导致在一些特殊情况下得多余。例如 5,4,3,1,2 的情况下,常规版会进行四次循环,但实际上第一次就已经完成排序了。
/*
* 优化: * 因为排序过程中,各元素不断接近自己的位置,如果一趟下来没有进行交换,就说明排序完成 * 因此 在排序过程中,设置一个flag来判断元素是否交换,,从而减少不必要的比较 * * */package sort;public class 冒泡排序 { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int arr[]={ -1,3,9,8,-2}; /*数组:arr[]={-1,3,9,8,-2} * 有五个元素,需要进行四次 大的比较 来确定 出最大值 ,最后一个值自然就不用比较了 * 第一次比较: 确定出最大值为 :9 确定过程需要 两两比较 比较四次 * 第二次比较: 确定出最大值为 :8 确定过程需要 两两比较 比较三次 * 第三次比较: 确定出最大值为 :3 确定过程需要 两两比较 比较两次 * 第四次比较: 确定出最大值为 :-1 确定过程需要 两两比较 比较一次 * * */ int temp=0; boolean flag=false; for (int i = 0; i < arr.length-1; i++) { for (int j = 0; j < arr.length-1-i; j++) { if(arr[j]>arr[j+1]){ flag = true;// temp=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; } } /* * 优化: * 因为排序过程中,各元素不断接近自己的位置,如果一趟下来没有进行交换,就说明排序完成 * 因此 在排序过程中,设置一个flag来判断元素是否交换,,从而减少不必要的比较 * * */ if(!flag){ break; }else{ flag=false; } System.out.println("第"+(i+1)+"次排序"); toArray(arr); } }//输出数组 public static void toArray(int[] arr) { for (int i = 0; i < arr.length; i++) { System.out.print(arr[i]+" "); } System.out.println("======="); } }
转载地址:http://sothn.baihongyu.com/