一、什么是鸡尾酒排序
1.概念
鸡尾酒排序算法又叫快乐小时排序,它基于冒泡排序算法做了一些优化。冒泡排序算法每一轮都是从左到右进行元素比较,进行单向的位置交换,鸡尾酒排序算法则是双向的元素比较和交换。
2.算法原理
这是一个无序数列:2、3、4、5、6、7、8、1,我们要将它按从小到大排序。按照冒泡排序算法的思想,每一轮将最大的元素移到最右边。
第一轮结果
第二轮结果
第三轮结果
第四轮结果
第五轮结果
第六轮结果
第七轮结果
可以看到该序列2到8已经是有序的,但还需进行7轮排序,而鸡尾酒算法可以很好地解决这一问题
鸡尾酒排序算法第一轮与冒泡排序一致,从左到右进行比较、交换
第二轮,则从右向左进行比较、交换
8已经是有序了,7和1比较,7大于1,7和1交换
接下来,6和1比较,6大于1,6和1交换
以此类推,第二轮交换结果如下所示
第三轮,从左到右进行比较,2和3比较,位置不变,3和4比较,位置不变,4和5比较,位置不变,5和6比较,位置不变,6和7比较,位置不变
第三轮,没有发生任何元素交换,说明序列已是有序的,排序结束。
3.算法实现
// 鸡尾酒排序算法
function sort(arr) {
let length = arr.length;
// 记录右侧最后一次交换位置
let lastRightExchangeIndex = 0;
// 记录左侧最后一次交换位置
let lastLeftExchangeIndex = 0;
// 无序数列的右边界,每次比较只需要比到这里为止
let rightSortBorder = length - 1;
// 无序数列的左边界,每次比较只需要比到这里为止
let leftSortBorder = 0;
for (let i = 0; i < length / 2; i++) {
let isSorted = true;
for (let j = i; j < rightSortBorder; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
isSorted = false;
lastRightExchangeIndex = j;
}
}
rightSortBorder = lastRightExchangeIndex;
if (isSorted) {
break;
}
for (let j = length - i - 1; j > leftSortBorder; j--) {
if (arr[j - 1] > arr[j]) {
[arr[j], arr[j - 1]] = [arr[j - 1], arr[j]];
isSorted = false;
lastLeftExchangeIndex = j;
}
}
leftSortBorder = lastLeftExchangeIndex;
if (isSorted) {
break;
}
}
}
let arr = [2, 3, 4, 5, 6, 7, 8, 1];
sort(arr);
console.log(arr);
鸡尾酒排序算法与冒泡排序算法一样,可以通过记录序列是否已经有序和最后一次交换顺序进行优化,代码中是已优化后的算法,具体优化原理可以参考十大经典排序算法-冒泡排序算法详解
二、鸡尾酒排序算法特点
1.复杂度和稳定性
鸡尾酒排序算法是对冒泡排序算法的优化,它的复杂度和稳定性和冒泡排序算法是一致的,时间复杂度为O(N^2),空间复杂度为O(1),是稳定排序算法。
2.优点
在特定条件下,通常指大部分元素都有序的场景下,可以减少排序的轮数。