鸡尾酒排序算法详解

一、什么是鸡尾酒排序

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.优点

在特定条件下,通常指大部分元素都有序的场景下,可以减少排序的轮数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值