排序算法の冒泡排序原理&代码&优化

文章详细介绍了冒泡排序的原理,提供了R语言的基本冒泡排序和优化后的实现,包括当一轮无交换时提前结束以及减少比较次数的优化。此外,还介绍了双向冒泡排序的概念和实现,这种排序方法通过左右同时进行比较以提高效率。文章最后给出了Java版本的双向冒泡排序代码。
摘要由CSDN通过智能技术生成

目录

一、冒泡排序的原理

 二、冒泡排序的代码实现(R)

 三、冒泡排序的优化(R)

四、终极.双向冒泡排序(R+Java)


一、冒泡排序的原理

气泡从水底往上走的过程中越来越大,同样冒泡排序每轮都会使得最大的元素排到最后,这就是冒泡排序名字的由来。

冒泡排序的核心思想就是重复依次比较相邻元素,你品,你细品,这是不是就是冒泡的感觉?!

 二、冒泡排序的代码实现(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]+" ");
		}
	}
 
}

 运行结果:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值