参考书籍:《漫画算法小灰的算法之旅》
(1)冒泡排序中,当数组后半部分的元素逐渐变得有序后,仍然会进行多次比较,从这一点进行优化。
设置变量记录有序区域,每次比较时仅仅比较无序区域的元素即可。
public class PubblesortTo { public static void main(String []args){ int array[] = {1,2,6,3,16,4,3,11,5}; pubbleSort03(array); for (int i = 0; i < array.length; i++) { System.out.print(array[i]+","); } } public static void pubbleSort03(int array[]){ //最后一次交换的下标 int LastExchangeIndex = 0; //有序边界 int SortBorder = array.length -1; for(int i = 0;iarray[j+1]){ tmp = array[j]; array[j] = array[j+1]; array[j+1] = tmp; //发生交换则将flag设置为false,即假设错误,数组并不是有序的 flag = false; LastExchangeIndex = j; } } SortBorder = LastExchangeIndex; if(flag){ break; } } } }
(2)鸡尾酒排序(双向冒泡排序,搅拌排序,来回排序)
常规冒泡排序存在着如下问题。
如图,只有1顺序不对,但仍需进行7轮排序。
鸡尾酒排序流程:
第三轮虽然已经有序,还是会从左到右进行一轮比较,没有元素进行位置交换,证明已经有序,排序结束。
思路:像钟摆一样,第一轮从左到右,第二轮从右到左,第三轮从左到右…
public class CocktailSort { public static void main(String []args){ int array[] = {1,2,6,3,16,4,3,11,1,5}; cocktailSort(array); for (int i = 0; i < array.length; i++) { System.out.print(array[i]+","); } } public static void cocktailSort(int []array){ int tmp = 0; //这里一个外层循环对应两个内层循环,因此使用数组长度/2 for (int i = 0; i < array.length /2 ; i++) { //flag设为true,假设此时数组有序 boolean flag = true; for(int j = i ;j< array.length - i -1;j++){ if(array[j]>array[j+1]){ tmp = array[j]; array[j] = array[j+1]; array[j+1] = tmp; //发生交换则假设错误,将flag设为flase flag = false; } } //flag为true表示假设正确,直接退出循环 if(flag){ break; } //开始偶数轮前重新置flag为true flag = true; //这里偶数轮采用反方向,因此从后往前遍历,for循环的条件改变 for(int j = array.length -1 -1;j>i ; j--){ //这里比较也是反方向 if (array[j] < array[j-1]) { tmp = array[j]; array[j] = array[j-1]; array[j-1] = tmp; flag = false;//同前 } } if(flag){ break; } } } }
鸡尾酒排序和上面的优化方法可以结合。
缺点:鸡尾酒排序代码量更大。优点:某些情况下可以大大节省资源。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)