優化的氣泡排序 —— 雞尾酒排序
阿新 • • 發佈:2019-02-15
雞尾酒排序是一種定向的氣泡排序(又叫快樂小時排序),排序是 從低到高 再 從高到低 的反覆。而氣泡排序是從低到高的排序。
先來看看氣泡排序
舉個栗子:
8個數組成一個無序數列:3、2、4、5、6、7、1、8,希望從小到大排序
第一輪結果( 3 和 2 交換,1 和 8 交換)
第二輪結果( 7 和 1 交換)
第三輪結果( 6 和 1 交換)
接下來(5和1交換,4和1交換,3和1交換,2和1交換)
最後結果為
總共進行了7次交換
下面用雞尾酒排序該無序數列
第一輪( 3 和 2 交換,8 和 1 交換)
第二輪
此時開始不一樣了,我們要從右到左(即高到低)進行交換、比較
即在這裡8已經在有序區域了,不考慮。讓1和7比較,1小於7,7和1交換
然後 6 和 1 交換,
5 和 1 交換,4 和 1 交換,3 和 1 交換, 2 和 1 交換
最終結果:
第三輪(結果已經有序了,但流程並沒有結束)
第三輪需要重新從左到右(從低到高)比較和交換
1和2比較,位置不變;2和3比較,位置不變, ...... ,6和7比較,位置不變
沒有元素位置交換,證明已經有序,排序結束
對於雙向雞尾酒排序,我們可以在每一輪排序的最後,記錄下最後一次元素交換的位置( rightChange 和 leftChange ),那個位置就是無序數列的邊界,再往後就是有序區了。
下面給出雙向的雞尾酒排序的java程式碼
public class CockTailSort { public static void main(String[] args){ int[] array=new int[]{3,2,4,5,6,7,8,1}; tailSort(array); System.out.println(Arrays.toString(array)); } private static void tailSort(int array[]){ int temp=0; //記錄最後一次左右交換的位置 int rightChange=0; int leftChange=0; //左右邊界 int right=array.length-1; int left=0; for(int i=0;i<array.length/2;i++){ //有序標記,每一輪的初始是true,數列有序的時候,沒有交換,跳出迴圈 boolean isSorted=true; //奇數輪,從左到右 for(int j=left;j<right;j++){ if(array[j]>array[j+1]){ temp=array[j]; array[j]=array[j+1]; array[j+1]=temp; //元素有交換,所以不是有序,標記變為false isSorted=false; rightChange=j; } } right=rightChange; if(isSorted){ break; } //偶數輪,從右到左 for(int j=right;j>left;j--){ if(array[j]<array[j-1]){ temp=array[j]; array[j]=array[j-1]; array[j-1]=temp; //元素有交換,所以不是有序,標記變為false isSorted=false; leftChange=j; } } left=leftChange; if(isSorted){ break; } } } }
該文章是看過其他人的整理講解,再寫出來給自己方便理解的。
雙向雞尾酒排序是針對數列大部分有序的情況的,而且雙向雞尾酒排序的缺點是:程式碼多