鸡尾酒(双向冒泡)排序
鸡尾酒搅拌(双向冒泡)排序本质上仍然是冒泡排序,与冒泡排序的区别是,每趟外层循环都产生一个最小值和一个最大值,分别放在队列的两端,以此类推,直到完成所有排序。下面是Java代码(将百度百科的Java代码稍作改动),
/**
* 鸡尾酒(双向冒泡)排序
* @param data
*/
public static void cocktailSort(int[] data)
{
//将最大值排到队尾
for(int i = 0 ; i < data.length/2 ; i++)
{
for(int j = i ; j < data.length-i-1 ; j++)
{
if(data[j] > data[j+1])
{
swap(data, j, j+1);
}
System.out.println("交换大"+Arrays.toString(data));
}
//将最小值排到队头
for(int j = data.length-1-(i+1); j > i ; j--)
{
if(data[j] < data[j-1])
{
swap(data, j, j-1);
}
System.out.println("交换小"+Arrays.toString(data));
}
System.out.println("第"+i+"次排序结果:"+Arrays.toString(data));
}
}
/**
* 数组内 i 坐标元素与 j 坐标元素互换
* @param data
* @param i
* @param j
*/
private static void swap(int[] data, int i, int j) {
int temp = data[i];
data[i] = data[j];
data[j] = temp;
}
说实话,上述代码尽管经典,但是看起来略微费劲,特别是j变量的取值和变化范围部分。我做了一些修改,自认为简单且符合思维。代码如下,
/**
* 鸡尾酒(双向冒泡)排序2
* @param data
*/
public static void cocktailSort2(int[] data)
{
int i = 0;
int length = data.length -1;
while (i < length)
{
//从后向前将最小值推到队头
for(int j = length ; j > i; j--)
{
if(data[j-1] > data[j])
{
swap(data, j-1, j);
}
System.out.println("交换小"+Arrays.toString(data));
}
i++;
//从前向后将最大值推到队尾
for(int j = i; j < length; j++)
{
if(data[j] > data[j+1])
{
swap(data, j, j+1);
}
System.out.println("交换大"+Arrays.toString(data));
}
length--;
System.out.println("第"+i+"次排序结果:"+Arrays.toString(data));
}
}
/**
* 数组内 i 坐标元素与 j 坐标元素互换
* @param data
* @param i
* @param j
*/
private static void swap(int[] data, int i, int j) {
int temp = data[i];
data[i] = data[j];
data[j] = temp;
}
同样的我们可以写出双向选择排序等,但归结到效率上,这种方式并没有实质性的提高算法效率,因此,这里只是作为了解,明了其原理和代码书写就行了。