一)算法介绍
鸡尾酒排序是一种定向的冒泡排序,也可以称为搅拌排序、涟漪排序。是冒泡排序的一种变形。
和冒泡排序的区别在于,鸡尾酒排序采用了双向比较并替换的原理。
二)算法原理
基本原理:
第一步:声明两个临时指针left和right,分别指向第一个元素和最后一个元素。
第二步:每一轮比较时,从right往left方向查找最大数,放到right位置,从left往right方向查找最小数,放到left位置。每查找完一遍之后,因为最大数和最小数位置已经确定好,所以把查找边界缩短,如left++、right--。
第三步:重复第二步操作,直到left和right相遇时,表示排序已完成了。
算法步骤图解:
源数据: int[] nums = { 7, 4, 5, 6, 9, 2, 8, 1, 3 }
第一轮排序:
先right方向,3>1,位置不变,3<8,交换位置,8>2,位置不变,8<9,交换位置,9依次和6547比,9最大。
结果为:[ 7, 4, 5, 6, 8, 2, 3, 1, 9 ]
再left方向,7>4,交换位置,4<5<6<8,位置不变,4>2,交换位置,2<3,位置不变,2>1,交换位置,1最小。
结果为:[ 1, 7, 5, 6, 8, 4, 3, 2, 9 ]
第二轮排序:
先right方向,2<3,交换位置,3<4,交换位置,4<8,交换位置,8依次和6571比,8最大。
结果为:[ 1, 7, 5, 6, 4, 3, 2, 8, 9 ]
再left方向,7>5,交换位置,5<6,位置不变,5>4,交换位置,4>3,交换位置,3>2,交换位置,2最小。
结果为:[1, 2, 7, 6, 5, 4, 3, 8, 9]
第三轮排序:
先right方向,3<4,交换位置,4<5,交换位置,5<6,交换位置,6<7,交换位置,7最大。
结果为:[1, 2, 6, 5, 4, 3, 7, 8, 9]
再left方向,6>5,交换位置,5>4,交换位置,4>3,交换位置,3最小。
结果为:[1, 2, 3, 6, 5, 4, 7, 8, 9]
最终排序:
先right方向,4<5,交换位置,5<6,交换位置,6最大。
结果为:[1, 2, 3, 5, 4, 6, 7, 8, 9]
再left方向,5>4,交换位置,4最小。
结果为:[1, 2, 3, 4, 5, 6, 7, 8, 9]
算法排序效果图:
算法复杂度:
最差情况:T(n) = O(n^2)
最好情况:T(n) = O(n)
// n=100;
// O(n)含义
for(i=0;i<100;i++){
}
// O(n^2)含义
for(i=0;i<100;i++) {
for(i=0;i<100;i++){
}
}
三)算法源码
步骤简介:声明left和right两个指针,每一轮排序时,把最小值放到left位置,把最大值放到right位置,直到排序完成。
/**
* 鸡尾酒排序: 采用了双向比较并替换的原理
* @param nums
*/
public static int[] cocktailSort(int[] nums) {
if (nums == null) {
return null;
}
int left = 0; // 第1个下标
int right = nums.length-1; // 最后1个下标
while (left < right) {
// 从right-1开始比较,把较大的数排列在后面
for (int i = right - 1; i >= left; i--) {
if (nums[i] > nums[right]) {
int temp = nums[i];
nums[i] = nums[right];
nums[right] = temp;
}
}
right--; // 缩短右边界
// 从left+1开始比较,把较小的数排列在前面
for (int i = left + 1; i <= right; i++) {
if (nums[i] < nums[left]) {
int temp = nums[i];
nums[i] = nums[left];
nums[left] = temp;
}
}
left++; // 缩短左边界
}
return nums;
}
识别二维码关注个人微信公众号
本章完结,待续、欢迎转载!
本文说明:该文章属于原创,如需转载,请标明文章转载来源!