• 冒泡排序


    冒泡排序

     

    ?>冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。


     

    1、原理

     每一趟只能确定将一个数归位。即第一趟只能确定将末位上的数归位,第二趟只能将倒数第 2 位上的数归位,依次类推下去。
     如果有 n 个数进行排序,只需将 n-1 个数归位,也就是要进行 n-1 趟操作。
     ​
     而 “每一趟 ” 都需要从第一位开始进行相邻的两个数的比较,将较大的数放后面,
     比较完毕之后向后挪一位继续比较下面两个相邻的两个数大小关系,重复此步骤,直到最后一个还没归位的数。 

     

    2、动图演示

    !>什么时候最快:当输入的数据已经是正序时(都已经是正序了,我还要你冒泡排序有何用啊)。

    !>什么时候最慢:当输入的数据是反序时(写一个 for 循环反序输出数据不就行了,干嘛要用你冒泡排序呢,我是闲的吗)。


     

    3、代码实现

    3.1 JavaScript 代码实现

     function bubbleSort(arr) {
         var len = arr.length;
         for (var i = 0; i < len - 1; i++) {
             for (var j = 0; j < len - 1 - i; j++) {
                 if (arr[j] > arr[j+1]) {        // 相邻元素两两对比
                     var temp = arr[j+1];        // 元素交换
                     arr[j+1] = arr[j];
                     arr[j] = temp;
                 }
             }
         }
         return arr;
     }
    

    3.2 Python 代码实现

     def bubbleSort(arr):
         for i in range(1, len(arr)):
             for j in range(0, len(arr)-i):
                 if arr[j] > arr[j+1]:
                     arr[j], arr[j + 1] = arr[j + 1], arr[j]
         return arr
    

    3.3 Go 代码实现

     func bubbleSort(arr []int) []int {
         length := len(arr)
         for i := 0; i < length; i++ {
             for j := 0; j < length-1-i; j++ {
                 if arr[j] > arr[j+1] {
                     arr[j], arr[j+1] = arr[j+1], arr[j]
                 }
             }
         }
         return arr
     }
    

    3.4 Java 代码实现

     public static void BubbleSort(int [] arr){
          int temp;//临时变量
          for(int i=0; i<arr.length-1; i++){   //表示趟数,一共arr.length-1次。
              for(int j=arr.length-1; j>i; j--){
     ​
                  if(arr[j] < arr[j-1]){
                      temp = arr[j];
                      arr[j] = arr[j-1];
                      arr[j-1] = temp;
                  }
              }
          }
      }

     

    4、优化(Java)

    针对问题(1):

    发现整个数列已经是有序的了 )– 数据的顺序排好之后,冒泡算法仍然会继续进行下一轮的比较,直到arr.length-1次,后面的比较没有意义的。

    方案:

    • 设置标志位flag,如果发生了交换flag设置为true;如果没有交换就设置为false。

    • 这样当一轮比较结束后如果flag仍为false,即:这一轮没有发生交换,说明数据的顺序已经排好,没有必要继续进行下去。

     public static void BubbleSort1(int [] arr){
         if (arr == null || arr.length < 2) {
             return arr;
         }
         int temp;//临时变量
         boolean flag;//是否交换的标志
         for(int i=0; i<arr.length-1; i++){   //表示趟数,一共arr.length-1次。
             flag = true;
             for(int j=arr.length-1; j>i; j--){
                 if(arr[j] < arr[j-1]){
                     temp = arr[j];
                     arr[j] = arr[j-1];
                     arr[j-1] = temp;
                     flag = false;//有元素交换,所以不是有序,标记变为false
                 }
             }
             //一趟下来是否发生位置交换,如果没有交换直接跳出大循环
             if(flag) break;
         }
     }
    

    针对问题(2):

    发现整个数列有序区的界定 )– 数据的顺序排好之后, 在一轮排序后,发现后面其实又是有序数列了,但是还是要每一次两两相比,这样也白白比较了很多次了 。

    图例:

    方案:

    • 记录最后一次交换的位置

     public static int[] BubbleSort(int[] arr) {
          if (arr == null || arr.length < 2) {
               return arr;
          }
         //记录最后一次交换的位置
         int lastExchangeIndex = 0;
         //无序数列的边界,每次比较只需要比到这里为止
         int sortBorder = arr.length - 1;
         
         for (int i = 0; i < arr.length - 1; i++) {
              boolean isSorted  = true;//有序标记,每一轮的初始是true
              for (int j = 0; j < sortBorder; j++) {
                  if (arr[j + 1] < arr[j]) {
                      isSorted  = false;//有元素交换,所以不是有序,标记变为false
                      int t = arr[j];
                      arr[j] = arr[j+1];
                      arr[j+1] = t;
                      lastExchangeIndex = j;
                  }
              }
             sortBorder = lastExchangeIndex
              //一趟下来是否发生位置交换,如果没有交换直接跳出大循环
              if(isSorted )
                   break;
          }
          return arr;
     }
    
  • 相关阅读:
    centos7 hpc高性能计算集群配置(无密码访问、nfs文件共享)
    dbGrid、cxGrid下拉列表做单、多列更新的三种实现方式
    delphi指针简单入门
    Delphi USB摄像头
    Delphi USB摄像头
    DelphiXE环境认知(第一章 Project Options)
    程序缩小到托盘后系统就无法关机(解决方案)
    TNotifyEvent
    关于Delphi在定义了函数进行调用时显示undeclared identifier的问题
    listview增加一行后,显示最后一条数据,进度条显示最底
  • 原文地址:https://www.cnblogs.com/mmdz/p/16170765.html
Copyright © 2020-2023  润新知