图解:冒泡排序升级之【鸡尾酒排序】

本文涉及的产品
性能测试 PTS,5000VUM额度
应用实时监控服务-应用监控,每月50GB免费额度
云原生网关 MSE Higress,422元/月
简介: 鸡尾酒排序,是冒泡排序算法的一种升级。冒泡排序的每个元素都可以像气泡一样,根据自身大小,一点点的向着数组的某侧移动。算法每一轮都是从左到右来比较元素,进行**单向**的位置交换的。而鸡尾酒排序是在此基础上元素比较和交换过程变成了**双向**的。固[鸡尾酒]排序又称双向冒泡排序、鸡尾酒搅拌排序、搅拌排序、涟漪排序、来回排序或快乐小时排序, 是冒泡排序的一种变形。

一.鸡尾酒排序概念

鸡尾酒排序,是冒泡排序算法的一种升级。冒泡排序的每个元素都可以像气泡一样,根据自身大小,一点点的向着数组的某侧移动。算法每一轮都是从左到右来比较元素,进行单向的位置交换的。而鸡尾酒排序是在此基础上元素比较和交换过程变成了双向的。固鸡尾酒排序又称双向冒泡排序、鸡尾酒搅拌排序、搅拌排序、涟漪排序、来回排序或快乐小时排序, 是冒泡排序的一种变形。

鸡尾酒排序最糟或是平均所花费的次数都是O(n²),但如果序列在一开始已经大部分排序过的话,会接近O(n)。

二. 逻辑推演

问题分析:

现有一个数组,里面的数据为: [2,3,4,5,6,7,8,1],我们以此数据来分析:

image-20211013110818725

冒泡排序过程如下:

image-20211013111356725

image-20211013162036391

结果分析:

元素 2、3、4、5、6、7、8已经是有序的了,只需要将元素1的放到正确的位置就可以了,却还是进行了7轮排序,这也太不方便了。要是能直接将1的位置进行调整,数列就有序了。鸡尾酒排序正是要解决这个问题的。

优化思路:

鸡尾酒详细过程:

第一轮(和冒泡排序一样,8和1交换)

image-20211013162754692

第二轮:此时开始不一样了,我们反过来从右往左比较进行交换。

image-20211013163352045

image-20211013163912858

第三轮:虽然实际上已经有序,但是流程并没有结束。

在鸡尾酒排序的第三轮,需要重新从左向右比较进行交换。

1和2比较,位置不变;2和3比较,位置不变;3和4比较,位置不变...7和8比较位置不变。没有元素进行交换,证明当前有序,排序结束。

小结:

本来需要7轮的排序场景,用3轮就解决了,鸡尾酒排序就是这样巧妙的算法。

而鸡尾酒排序的思路,排序过程就像钟摆一样,第一轮从左往右比较,第二轮从右往左比较,第三轮再从左往右比较...

三.鸡尾酒排序算法

代码:

    public static void sort(int[] array) {
   
   
        //循环计数
        int count = 0;
        //数据交换临时变量
        int tmp = 0;
        for (int i = 0; i < array.length / 2; i++) {
   
   
            System.out.println("第" + (++count) + "次循环");
            //每轮的初始值都是true,有序标记:true代表有序
            boolean isSorted = true;
            //奇数轮,从左向右比较和交换
            for (int j = i; j < array.length - i - 1; j++) {
   
   

                if (array[j] > array[j + 1]) {
   
   
                    tmp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = tmp;
                    //发生交换,不是有序,标记改成false
                    isSorted = false;
                }
            }
            //是否有序
            if (isSorted) {
   
   
                break;
            }
            //在偶数轮之前,将isSorted重新标记为true
            isSorted = true;
            System.out.println("第" + (++count) + "次循环");
            //偶数轮,方向从右向左比较和交换
            for (int j = array.length - i - 1; j > i; j--) {
   
   
                if (array[j] < array[j - 1]) {
   
   
                    tmp = array[j];
                    array[j] = array[j - 1];
                    array[j - 1] = tmp;
                    isSorted = false;
                }
            }
            //是否有序
            if (isSorted) {
   
   
                break;
            }
        }
    }

结果输出:

第1次循环
第2次循环
第3次循环
[1, 2, 3, 4, 5, 6, 7, 8]

总结:

这段代码是鸡尾酒排序的原始实现。代码外部的大循环控制所有排序回合,大循环内部包含两个小循环,第1个小循环从左往右比较并交换元素,第2个小循环从右往左比较并交换元素。

鸡尾酒的优势是,在大部分元素已经有序的情况下,减少排序的回合数;而缺点也很明显,就是代码量几乎翻了一倍。

目录
相关文章
|
算法 搜索推荐 程序员
初阶算法(1):通过简单的排序算法来认识时间复杂度
初阶算法(1):通过简单的排序算法来认识时间复杂度
|
7月前
|
算法 搜索推荐 Java
图解冒泡排序
图解冒泡排序
51 4
|
2月前
|
算法 搜索推荐
数据结构与算法学习十一:冒泡排序、选择排序、插入排序
本文介绍了冒泡排序、选择排序和插入排序三种基础排序算法的原理、实现代码和测试结果。
24 0
数据结构与算法学习十一:冒泡排序、选择排序、插入排序
|
7月前
|
搜索推荐 算法 Python
不了解冒泡排序的原理?
不了解冒泡排序的原理?
57 5
|
存储 人工智能 搜索推荐
冒泡排序:了解原理与实现
冒泡排序:了解原理与实现
94 0
|
算法 搜索推荐
初阶算法(2):进行详细地介绍插入排序的细节和时间复杂度
初阶算法(2):进行详细地介绍插入排序的细节和时间复杂度
|
搜索推荐
冒泡排序的原理
冒泡排序算法的原理如下: 1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。 2.对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。 3.针对所有的元素重复以上的步骤,除了最后一个。 4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比比较 白话就是:比如有6个数,你需要比较5趟,这个是固定死的
248 0
冒泡排序图解
冒泡排序图解
65 0
|
算法 搜索推荐
【21天算法学习】冒泡排序
【21天算法学习】冒泡排序
76 0
|
算法 搜索推荐 索引
选择排序图解
选择排序图解
116 0
选择排序图解