雞尾酒排序是一種定向的冒泡排序(又叫快樂小時排序),排序是 從低到高 再 從高到低 的反覆。而冒泡排序是從低到高的排序。
先來看看冒泡排序
舉個栗子:
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;
}
}
}
}
該文章是看過其他人的整理講解,再寫出來給自己方便理解的。
雙向雞尾酒排序是針對數列大部分有序的情況的,而且雙向雞尾酒排序的缺點是:代碼多