冒泡排序概览(java+R_优化以及双向冒泡代码)


排序

基本概念

定义

排序的含义:

对含有多个记录的文件进行整理,最终使得各个记录按关键字递增( 或递减)的次序排列起来。这个整理的过程称为排序。

排序分类方法

  1. 具有相同关键字的记录次序是否变化:
  • 稳定
  • 不稳定

image.png

  1. 是否需要内外存交换
    1. 内部排序:排序过程中,不涉及内外存的交换,适用于记录个数不多的小文件
    2. 外部排序:记录的个数太多,不能一次将全部记录放入内存的大文件

内部排序的分类:

  • 插入排序
  • 选择排序
  • 交换排序
  • 归并排序

我们讨论的重点是内部排序,而每一种排序方法的实现都依赖于记录在内存的存储结构。

  1. 根据复杂度不同分类

image.png

  1. 文件采用下列三种存储结构

image.png

  1. 排序算法的衡量标准

image.png

  1. 排序的目的:为了方便查找

冒泡排序

第一轮:
image.png
第二轮
image.png
第三轮
image.png
第四轮
image.png
第五轮
image.png

算法步骤

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾最后一对。这步做完后,最后的格子是最大的数。
  3. 针对所有的元素重复以上的步骤,出来最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

算法代码

Java版(优化)
package Bioinformatics_code.Sort;

import java.util.Arrays;

public class BubbleSort {
//    public static void swap(int a,int b){
//        int temp = a;
//        a = b;
//        b = temp;
//    }

    public static int[] bubbleSort(int[] sourceArray){
        // 对 array 进行拷贝,不改变参数内容
        int[] array = Arrays.copyOf(sourceArray, sourceArray.length);
        for (int i = 1;i<array.length;i++){
            boolean flag = true;
            for (int j = 0;j<array.length-i;j++){
                if (array[j]>array[j+1]){
                    int temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                    flag = false;
                }
            }
            if (flag) break;//这一行要放在第一个循环里面,第二个循环外面
        }
        return array;
    }

    public static void main(String[] args) throws Exception {
//        int a = 1;
//        int b = 2;
//        swap(a,b);
//        System.out.println(a+"+"+b);
        int[] array = bubbleSort(new int[]{1,2,3,4,7,42,13,4,67});
        System.out.println(Arrays.toString(array));
    }
}

Java版(双向冒泡)
package Bioinformatics_code.Sort;

import java.util.Arrays;
import java.util.Scanner;

public class DoubleBubbleSort {
    public static void main(String[] args) {
        int left;
        int right;
        int n;
        int i = 0;
        Scanner scanner1 = new Scanner(System.in);
        System.out.print("请输入你要排序的数字个数:");
        n = scanner1.nextInt();
        int[] array = new int[n];
        left = 0;
        right = n-1;
        Scanner scanner2 = new Scanner(System.in);
        System.out.println("请输入你需要排序的数组");
        while (scanner2.hasNextLine()){
            if (i == n) break;
            array[i] = scanner2.nextInt();
            i++;

        }
        System.out.println("未排序前:"+Arrays.toString(array));
        while(left < right){
            boolean IsSort_1 = true;
            for (int j = 0;j < right;j++){
                if (array[j] > array[j+1]) {
                    int temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                    IsSort_1 = false;
                }
            }
            if (IsSort_1) {
                break;
            }
            right--;
            boolean IsSort_2 = true;
            for (int j = right;j > left;j--){
                if (array[j] < array[j-1]) {
                    int temp = array[j];
                    array[j] = array[j-1];
                    array[j-1] = temp;
                    IsSort_2 = false;
                }
            }
            if (IsSort_2) {
                break;
            }
            left++;
            System.out.println("排序中:"+ Arrays.toString(array));
        }
        System.out.println("最终结果:"+Arrays.toString(array));
    }
}

R语言版(优化)
#bubblesort
bubbleSort <- 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(sortBorder)
    print(array)
  }
  return(array)
}

算法分析

  • 最好情况下:文件初始为正态,则一趟扫描就可完成排序。关键字的 比较次数为n-1,且没有记录移动,即O(n)。
  • 最坏情况下:文件初始是反态,则需进行n-1次排序,每趟排序要n-i(1<=i<=n-1)次比较,每次比较都必须移动记录三次来达到交换记录的目的。

比较次数:Cmax=n(n-1)/2=O(nn)
移动次数:3Cmax=O(n
n)

所以:

冒泡排序的最坏时间复杂度为O(n*n)

平均时间复杂度为O(n*n)

冒泡排序是稳定的

算法优化

疑问:

最后一轮排序时,整个序列已经是有序的了,是排序算法仍然兢兢业业的继续执行了后面的排序。
如果能判断出数列有序,并作出标记,那么剩下的几轮排序就不必执行了。

第一轮
image.png
第二轮
image.png
第三轮
image.png
第四轮
image.png
第五轮
image.png

如果某轮排序中没有发生交换操作,说明整个队伍已经有序。
算法操作:引用一个布尔量isSort判断是否发生了交换:每趟排序前先将它置为ture,排序过程中若有交换,则isSort置为true。当一趟排序结束时,我们再检查isSort,若仍为ture便终止算法。

image.png
其实右边已经是有序的了,可是每一轮还白白比较了很多次。

  1. 优化方法:

在每趟扫描中,记录最后一次交换发生的位置k,因为该位置以前的相邻记录都已排了序,所以下一趟扫描终止于k,而不必进行到预定的下界i。

#bubblesort
bubbleSort3 <- function(arrayy) {
  n <- length(arrayy)
  lastchange <- 1
  sortBorder <- n - 1
  for (i in 1:(n - 1)) {
    isSort <- TRUE
    for (j in 1:sortBorder) {
      if (arrayy[j] > arrayy[j + 1]) {
        temp <- arrayy[j]
        arrayy[j] <- arrayy[j + 1]
        arrayy[j + 1] <- temp
        isSort <- FALSE
        lastchange <- j
      }
      #print(arrayy)
    }
    sortBorder <- lastchange;
    if (isSort == TRUE) {
      break;
    }
    print(sortBorder)
    print(arrayy)
  }
  return(arrayy)
}

后面会继续更新其他排序,本文中大部分代码是我自己写的,可能有需要改进的地方,
希望能帮到你

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gremmie2003

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值