持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天,点击查看活动详情
前言
冒泡排序是一种基于交换的排序,实现简单,易于理解。一般在实现冒泡排序时都是从一个方向开始向另一个方向冒泡,本文在传统冒泡排序基础上介绍冒泡排序的另一种实现方式,采用快排双向遍历的方式,实现双向冒泡。
冒泡排序概述
基本思想:冒泡排序是从后往前(或者从前往后)一次两两比较相邻元素,若为逆序,则进行交换,直到比较到最后两个元素,这成为一趟排序,将最小元素交换到待排序序列的第一个位置(或将最大元素交换到待排序序列的最后一个位置。
关键字最小的元素像气泡一样向上“漂浮”到水面,所以成为冒泡排序。
冒泡排序的过程:第一趟冒泡时: 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标志,当一趟循环中没有进行交换说明序列已经有序,直接结束。
通过测试看出在序列逆序时,Flag标志没有作用,但是当序列有序时,Flag标志可以使程序提前结束,有效减少了比较次数。
双向冒泡排序
双向冒泡排序的过程:第一次从后往前冒泡时: 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++;
}
}