鸡尾酒排序
鸡尾酒排序其实冒泡排序的一种变形,或者说改进。又称为涟漪排序。单从鸡尾酒这个名字看不出来到底是如何实现排序。
常见的冒泡排序是始终是按一个方向来进行排序,找到最大或者最小值。而鸡尾酒排序则是按一个方向找到最大(小)值,然后再按另外一个方向找到最小(大)值。然后交替操作,直到排序完成,这有没有一点像在不断地搅动酒杯啊!(因此也被称作来回排序的原因吧)
为了直观的展示鸡尾酒排序的过程,使用一个动态图视频来展示。一下链接是动画展示
wikihttp://upload.wikimedia.org/wikipedia/commons/e/ef/Sorting_shaker_sort_anim.gif的展示,如果不好看出来,也也可以下载看我制作了一个视频:
在下边的“附件下载”有链接(只有800k大小)
从视频中可以明显看出来,在从左到右的冒泡过程是将最大值(未排序的数据中)放在最后(已排好数据的左边),而从右向左的冒泡过程中是将最小值(未排序的数据中)放在最左边(已排好的数据右边)。
明白原理编写代码就迎刃而解了:
#include<stdio.h>
#include<stdlib.h>
#define NUM_DATA11
void swap(int*a,int *b)
{
int temp;
temp=a[0];
a[0]=b[0];
b[0]=temp;
}
voidcocktail_sort(int *data,int num)
{
int i;
int low_index=0;
int high_index=num-1;
if(num==1)
{
return;
}
while(low_index<=high_index)//循环条件,
{
for(i=low_index+1;i<=high_index;i++)//从左到右冒泡
{
if( data[i] < data[i-1])
swap(&data[i],&data[i-1]);
}
high_index--;
for(i=high_index-1;i>=low_index;i--)//从右到左冒泡
{
if( data[i] > data[i+1])
swap(&data[i],&data[i+1]);
}
low_index++;
}
}
intsort_data[NUM_DATA];
int main(void)
{
int i;
for(i=0;i<NUM_DATA;i++)//初始化
{
sort_data[i]=rand();
}
cocktail_sort(sort_data,NUM_DATA);
for(i=0;i<NUM_DATA;i++)
{
printf("%d\n",sort_data[i]);
}
return 0;
}
NUM_DATA=10 NUM_DATA=11
证明对数据为奇数和偶数两种情况,算法均成立!
既然有了冒泡排序,为什么又会发展出鸡尾酒排序呢,下面对二者的性能做下对比
下图是分别是1000、5000和10000点数据进行排序的结果
1000点
6000点 10000点
对比二者可以看出,鸡尾酒排序的性能不会差于冒泡排序。
造成这一现象是因为——引用网上的一个正例来解释
“以序列(2,3,4,5,1)为例,鸡尾酒排序只需要访问两次(升序降序各一次)次序列就可以完成排序,但如果使用冒泡排序则需要四次。”
下面是反例
但是如果我的数组完全是逆序的(5,4,3,2,1),二者的花费时间是相同的!
总结:采用鸡尾酒排序改进,性能至少不会变坏,大多数情况是可以获得较好的性能提升!
转载于:https://blog.51cto.com/zjd1988/1340798