鸡尾酒排序
转自微信公众号——程序员小灰
https://mp.weixin.qq.com/s/CoVZrvis6BnxBQgQrdc5kA
让我们首先来回顾一下冒泡排序的思想:
冒泡排序的每一个元素都可以像小气泡一样,根据自身大小,一点一点向着数组的一侧移动。算法的每一轮从都是从左到右比较元素,进行单向的位置交换。
那么鸡尾酒排序做了怎样的优化呢?
鸡尾酒排序的元素比较和交换过程是双向的。
让我们来举一个栗子:
有8个数组成一个无序数列:2,3,4,5,6,7,8,1,希望从小到大排序。
如果按照冒泡排序的思想,排序的过程是什么样呢?
第一轮结果(8和1交换)
第二轮结果(7和1交换)
第三轮结果(6和1交换)
第四轮结果(5和1交换)
第五轮结果(4和1交换)
第六轮结果(3和1交换)
第七轮结果(2和1交换)
鸡尾酒排序是什么样子呢?让我们来看一看详细过程:
第一轮(和冒泡排序一样,8和1交换)
第二轮
此时开始不一样了,我们反过来从右往左比较和交换:
8已经处于有序区,我们忽略掉8,让1和7比较。元素1小于7,所以1和7交换位置:
接下来1和6比较,元素1小于6,所以1和6交换位置:
接下来1和5比较,元素1小于5,所以1和5交换位置:
接下来1和4交换,1和3交换,1和2交换,最终成为了下面的结果:
第三轮(虽然已经有序,但是流程并没有结束)
鸡尾酒排序的第三轮,需要重新从左向右比较和交换:
1和2比较,位置不变;2和3比较,位置不变;3和4比较,位置不变......6和7比较,位置不变。
没有元素位置交换,证明已经有序,排序结束。
这就是鸡尾酒排序的思路。排序过程就像钟摆一样,第一轮从左到右,第二轮从右到左,第三轮再从左到右......
public class CockTailSort {
-
private static void sort(int array[]) -
{ -
int tmp = 0; -
for(int i=0; i<array.length/2; i++) -
{ -
//有序标记,每一轮的初始是true -
boolean isSorted = 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; -
//有元素交换,所以不是有序,标记变为false -
isSorted = false; -
} -
} -
if(isSorted){ -
break; -
}
//偶数轮之前,重新标记为true
-
isSorted = true; -
//偶数轮,从右向左比较和交换 -
for(int j=array.length-i-1; j>i; j--) -
{ -
if(array[j] < array[j-1]) -
{ -
tmp = array[j]; -
array[j] = array[j-1]; -
array[j-1] = tmp; -
//有元素交换,所以不是有序,标记变为false -
isSorted = false; -
} -
} -
if(isSorted){ -
break; -
} -
} -
} -
-
public static void main(String[] args){ -
int[] array = new int[]{2,3,4,5,6,7,8,1}; -
sort(array); -
System.out.println(Arrays.toString(array)); -
}
}
这段代码是鸡尾酒排序的原始实现。代码外层的大循环控制着所有排序回合,大循环内包含两个小循环,第一个循环从左向右比较并交换元素,第二个循环从右向左比较并交换元素。
浙公网安备 33010602011771号