目录
一、冒泡排序的原理
气泡从水底往上走的过程中越来越大,同样冒泡排序每轮都会使得最大的元素排到最后,这就是冒泡排序名字的由来。
冒泡排序的核心思想就是重复依次比较相邻元素,你品,你细品,这是不是就是冒泡的感觉?!
二、冒泡排序的代码实现(R)
基于核心思想我们写出代码(R语言为例).
BubbleSort1=function(array){
n=length(array)#待排序数组长度
for(i in 1:(n-1)){
for(j in 1:(n-i)){
if(array[j]>array[j+1]){#相邻元素的比较与互换
temp=array[j]
array[j]=array[j+1]
array[j+1]=temp
}
}
print(array)
}
return(array)
}
同样,大家思考几个问题,为什么大循环是n-1次,小循环是n-i次?这有助于大家更好的理解和掌握排序算法。
因为,每轮(i)比较会产出1个最大的数(第i大的数),比较n-1轮时,剩下的1个元素一定是最小的,无需再比了。也就不难理解,每轮会从未排的最大元素放到最后,所以第i轮的后面i个元素已经有序,无需再排。
以5,1,4,2,8数组为例,下图是冒泡排序的示意图,黄色为正在进行比较的元素,橙色为已经排好的元素。
三、冒泡排序的优化(R)
【优化1】如果某轮没有发生交换操作,说明整个队伍已经有序,那么大循环就可以结束了。当待排序的数组非常大时,算法的优化可以大大节省时间。
#引入判断变量isSort,每轮结束时对其进行检查
BubbleSort2=function(array){
n=length(array)
for(i in 1:(n-1)){
isSort=TRUE
for(j in 1:(n-i)){
if(array[j]>array[j+1]){
temp=array[j]
array[j]=array[j+1]
array[j+1]=temp
isSort=FALSE
}
}
if(isSort==TRUE){
break
}
print(array)
}
return(array)
}
【优化2】如果某一轮中,某一对相邻元素无需交换,那么小循环可以结束了
#引入lastchange,lastchange到i已经有序
BubbleSort3=function(array){
n=length(array)
lastchange=1
sortBorder=n-1
for(i in 1:(n-1)){
isSort=TRUE
for(j in 1:sortBorder){
if(array[j]>array[j+1]){
temp=array[j]
array[j]=array[j+1]
array[j+1]=temp
isSort=FALSE
lastchange=j
}
}
sortborder=lastchange
if(isSort==TRUE){
break
}
print(array)
}
return(array)
}
四、终极.双向冒泡排序(R+Java)
前面介绍的无论是基础还是优化,都是从左到右扫描,双向冒泡排序,顾名思义,左右开弓,速度可谓是杠杠的。
其实就是对上面【优化2】的升级,左右同时多了一个lastchange来缩短每轮比较的元素个数
#优化3,双向冒泡
BidirectionalBubblesort <- function(array){
n <- length(array)
for (i in 1:(n/2)) {
judge <- FALSE
for (j in 1:(n-i)) {
if(array[j]>array[j+1]){
temp <- array[j]
array[j] <- array[j+1]
array[j+1] <- temp
judge <- TRUE
}
}
if(!judge){
break
}
judge <- FALSE
for (j in n:(i+1)) {
if(array[j]<array[j-1]){
temp <- array[j]
array[j] <- array[j-1]
array[j-1] <- temp
judge <- TRUE
}
}
if(!judge){
break
}
}
print(array)
}
再给大家参考一下我写的双向冒泡的java代码:
package work;
import java.util.*;
public class BidirectionalBubbleSort {
public static void main(String[] args) {
System.out.println("输入待排序的数组");
Scanner scan=new Scanner(System.in);
String str=scan.nextLine();
int len=(str.length()+1)/2;
Scanner ea=new Scanner(str);
int[] array=new int[len];
int j=0;
while(ea.hasNext()) {
array[j]=Integer.parseInt(ea.next());
j++;
}
BBS(array);
}
static void BBS(int[] array) {
int left=0,right=array.length-1,le,ri;
while(left<right) {
le=left+1;
ri=right-1;
for(int i=left;i<right;i++) {
if(array[i]>array[i+1]) {
int temp=array[i];
array[i]=array[i+1];
array[i+1]=temp;
ri=i;
}
}
right=ri;
for(int i=right;i>left;i--) {
if(array[i]<array[i-1]) {
int temp=array[i];
array[i]=array[i-1];
array[i-1]=temp;
le=i;
}
}
left=le;
}
System.out.println("冒泡排序后的数组为:");
for(int i=0;i<array.length;i++) {
System.out.print(array[i]+" ");
}
}
}
运行结果: