利用快排思想的冒泡排序

195 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天,点击查看活动详情

前言

冒泡排序是一种基于交换的排序,实现简单,易于理解。一般在实现冒泡排序时都是从一个方向开始向另一个方向冒泡,本文在传统冒泡排序基础上介绍冒泡排序的另一种实现方式,采用快排双向遍历的方式,实现双向冒泡。

冒泡排序概述

基本思想:冒泡排序是从后往前(或者从前往后)一次两两比较相邻元素,若为逆序,则进行交换,直到比较到最后两个元素,这成为一趟排序,将最小元素交换到待排序序列的第一个位置(或将最大元素交换到待排序序列的最后一个位置。

关键字最小的元素像气泡一样向上“漂浮”到水面,所以成为冒泡排序。

冒泡排序 (2).png 冒泡排序的过程:第一趟冒泡时: 27<49,不交换;13<27,不交换:76>13,交换;97>13,交换;65>13,交换;38>13,交换:49>13,交换。通过第一趟冒泡后,最小元素已交换到第一个位置,也是它的最终位置。第二趟冒泡时对剩余子序列采用同样方法进行排序,以此类推,到第五趟结束后没有发生交换,说明表已有序,冒泡排序结束。

双向冒泡排序

首先还是先看一下基本单向冒泡排序

单向冒泡排序

public static void  BubbleMiddle(int[] src){
    int len = src.length;
    for(int i = 0; i < len; i++){
        //交换标志
        boolean flag = false;
        for(int j = len - 1 ; j > i; j--){
            if(src[j] < src [j-1]){
                flag = true;
                int temp = src[j];
                src[j] = src[j-1];
                src[j-1] = temp;
            }
            //当一趟中没有交换,说明数组已经有序
            if(flag == false){
                return;
            }

        }
    }
}

单向排序时,从后往前将最小元素向前冒泡,设置Flag标志,当一趟循环中没有进行交换说明序列已经有序,直接结束。

Snipaste_2022-10-27_16-58-38.jpg 通过测试看出在序列逆序时,Flag标志没有作用,但是当序列有序时,Flag标志可以使程序提前结束,有效减少了比较次数。

双向冒泡排序

未命名文件 (31).png 双向冒泡排序的过程:第一次从后往前冒泡时: 27<49,不交换;13<27,不交换:76>13,交换;97>13,交换;65>13,交换;38>13,交换:49>13,交换。通过第一次冒泡后,最小元素已交换到第一个位置,也是它的最终位置。第次从前往后冒泡时对剩余子序列采用同样方法进行排序,最大元素96交换到最后一个位置,以此类推,第三次排序时排序完成。

//双向冒泡排序
public static void BubbleTwoWay(int [] src){
    int low = 0, high = src.length-1;
    boolean flag = true;
    while (low < high && flag){
        flag = false;
        for(int i = low; i < high; i++){ //从前向后冒泡
            if(src[i] > src[i+1]){ //发生逆序,交换
                int temp = src[i];
                src[i] = src[i+1];
                src[i+1] = temp;
                flag = true;
            }
        }
        //更新上界
        high--;
        for(int j = high; j > low; j--){ //从后向前冒泡
            if(src[j] < src[j-1]){//发生逆序,交换
                flag = true;
                int temp = src[j];
                src[j] = src[j-1];
                src[j-1] = temp;
            }
        }
        //更新下界
        low++;
    }

}