最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java 排序算法之冒泡排序

 更新時間:2021年09月01日 15:46:16   作者:天然呆dull  
這篇文章主要介紹了java 排序算法之冒泡排序,文中運用大量的代碼講解相關知識,非常詳細,感興趣的小伙伴可以參考一下

基本介紹

冒泡排序(Bubble Sorting)(時間復雜度為 O(n²))的基本思想:通過對待排序序列 從前向后(從下標較小的元素開始),依次比較相鄰元素的值,若發(fā)現(xiàn)逆序則交換,使值較大的元素逐漸從前移向后部,就像水底下的旗袍一樣逐漸向上冒。

優(yōu)化點:因為排序過程中,個元素不斷接近自己的位置,如果一趟比較下來沒有進行過交換,就說明序列有序,因此要在排序過程中設置一個標志判斷元素是否進行過交換。從而減少不必要的比較。(該優(yōu)化點可以在完成基本的冒泡排序之后再做)

圖解冒泡排序算法的過程

動圖:

冒泡排序小結:

1.共進行 數(shù)組大小 - 1 次大的循環(huán)

2.每一趟排序的次數(shù)在逐漸的減少

3.優(yōu)化:如果發(fā)現(xiàn)在某趟排序中,沒有發(fā)生一次交換,則可以提前結束冒泡排序。

代碼實現(xiàn)

演變過程

為了容易理解,先演示冒泡排序的演變過程

    /**
     * 為了更好的理解,這里把冒泡排序的演變過程演示出來
     */
    @Test
    public void processDemo() {
        int arr[] = {3, 9, -1, 10, -2};

        // 第 1 趟排序:將最大的數(shù)排在最后
        // 總共排序:arr.length - 1
        int temp = 0; // 臨時變量,交換的時候使用
        for (int i = 0; i < arr.length - 1; i++) {
            if (arr[i] > arr[i + 1]) {
                temp = arr[i];
                arr[i] = arr[i + 1];
                arr[i + 1] = temp;
            }
        }
        System.out.println("第 1 趟排序后的數(shù)組");
        System.out.println(Arrays.toString(arr));

        // 第 2 趟排序:將第 2 大的數(shù)排在倒數(shù)第 2 位
        // 總共排序:arr.length - 1 - 1  ;
        // 從頭開始排序,其他沒有變化,只是將排序次數(shù)減少了一次
        for (int i = 0; i < arr.length - 1 -1; i++) {
            if (arr[i] > arr[i + 1]) {
                temp = arr[i];
                arr[i] = arr[i + 1];
                arr[i + 1] = temp;
            }
        }
        System.out.println("第 2 趟排序后的數(shù)組");
        System.out.println(Arrays.toString(arr));

        // 第 3 趟排序:將第 3 大的數(shù)排在倒數(shù)第 3 位
        // 總共排序:arr.length - 1 - 2  ;
        // 從頭開始排序,其他沒有變化,只是將排序次數(shù)減少了 2 次
        for (int i = 0; i < arr.length - 1 -2; i++) {
            if (arr[i] > arr[i + 1]) {
                temp = arr[i];
                arr[i] = arr[i + 1];
                arr[i + 1] = temp;
            }
        }
        System.out.println("第 3 趟排序后的數(shù)組");
        System.out.println(Arrays.toString(arr));

        // 第 4 趟排序:將第 4 大的數(shù)排在倒數(shù)第 4 位
        // 總共排序:arr.length - 1 - 3  ;
        // 從頭開始排序,其他沒有變化,只是將排序次數(shù)減少了 3 次
        for (int i = 0; i < arr.length - 1 -3; i++) {
            if (arr[i] > arr[i + 1]) {
                temp = arr[i];
                arr[i] = arr[i + 1];
                arr[i + 1] = temp;
            }
        }
        System.out.println("第 4 趟排序后的數(shù)組");
        System.out.println(Arrays.toString(arr));

        // 第 5 趟沒有必要,因為這里有 5 個數(shù)字,確定了 4 個數(shù)字,剩下的那一個就已經(jīng)出來了
    }

測試輸出

第 1 趟排序后的數(shù)組
[3, -1, 9, -2, 10]
第 2 趟排序后的數(shù)組
[-1, 3, -2, 9, 10]
第 3 趟排序后的數(shù)組
[-1, -2, 3, 9, 10]
第 4 趟排序后的數(shù)組
[-2, -1, 3, 9, 10]

從上述的 4 趟排序過程來看,循環(huán)體都是一樣的,只是每次循環(huán)的次數(shù)在減少,那么就可以如下簡化

@Test
public void processDemo2() {
  int arr[] = {3, 9, -1, 10, -2};

  // 總共排序:arr.length - 1
  int temp = 0; // 臨時變量,交換的時候使用
  for (int j = 0; j < arr.length - 1; j++) {
    for (int i = 0; i < arr.length - 1 - j; i++) {
      if (arr[i] > arr[i + 1]) {
        temp = arr[i];
        arr[i] = arr[i + 1];
        arr[i + 1] = temp;
      }
    }
    System.out.println("第 " + (j + 1) + " 趟排序后的數(shù)組");
    System.out.println(Arrays.toString(arr));
  }
}

測試輸出

第 1 趟排序后的數(shù)組
[3, -1, 9, -2, 10]
第 2 趟排序后的數(shù)組
[-1, 3, -2, 9, 10]
第 3 趟排序后的數(shù)組
[-1, -2, 3, 9, 10]
第 4 趟排序后的數(shù)組
[-2, -1, 3, 9, 10]

優(yōu)化

對于優(yōu)化,減少排序次數(shù)

    @Test
    public void processDemo3() {
        int arr[] = {3, 9, -1, 10, 20};

        // 總共排序:arr.length - 1
        int temp = 0; // 臨時變量,交換的時候使用
        boolean change = false;// 標識變量,表示是否進行過交換
        for (int j = 0; j < arr.length - 1; j++) {
            for (int i = 0; i < arr.length - 1 - j; i++) {
                if (arr[i] > arr[i + 1]) {
                    temp = arr[i];
                    arr[i] = arr[i + 1];
                    arr[i + 1] = temp;
                    change = true;
                }
            }
            if(!change){
                // 如果有 1 輪下來,都沒有進行排序,則可以提前退出
                break;
            }else{
                change = false; // 重置 change!!!, 進行下次判斷
            }
            System.out.println("第 " + (j + 1) + " 趟排序后的數(shù)組");
            System.out.println(Arrays.toString(arr));
        }
    }

測試輸出:

第 1 趟排序后的數(shù)組
[3, -1, 9, 10, 20]
第 2 趟排序后的數(shù)組
[-1, 3, 9, 10, 20]

這里更改了原始數(shù)組,因為優(yōu)化的點,得看你這個數(shù)組原來的排序 和 元素組成,算是一種概率問題,并不是在任何情況下都可以被優(yōu)化

封裝算法

    /**
     * 把排序算法封裝成一個方法,方便被復用
     *
     * @param arr
     */
    public static void bubbleSort(int[] arr) {
        // 總共排序:arr.length - 1
        int temp = 0; // 臨時變量,交換的時候使用
        boolean change = false;
        for (int j = 0; j < arr.length - 1; j++) {
            for (int i = 0; i < arr.length - 1 - j; i++) {
                if (arr[i] > arr[i + 1]) {
                    temp = arr[i];
                    arr[i] = arr[i + 1];
                    arr[i + 1] = temp;
                    change = true;
                }
            }
            if(!change){
                // 如果有 1 輪下來,都沒有進行排序,則可以提前退出
                break;
            }else{
                change = false; // 重置 change!!!, 進行下次判斷
            }
        }
    }

測試調用

    /**
     * 測試封裝后的算法
     */
    @Test
    public void bubbleSortTest() {
        int[] arr = {3, 9, -1, 10, 20};
        System.out.println("排序前:" + Arrays.toString(arr));
        bubbleSort(arr);
        System.out.println("排序后:" + Arrays.toString(arr));
    }
    

測試輸出

排序前:[3, 9, -1, 10, 20]
排序后:[-1, 3, 9, 10, 20]

大量數(shù)據(jù)耗時測試

排序隨機生成的 8 萬個數(shù)據(jù)

    /**
     * 大量數(shù)據(jù)排序時間測試
     */
    @Test
    public void bulkDataSort() {
        int max = 80000;
        int[] arr = new int[max];
        for (int i = 0; i < max; i++) {
            arr[i] = (int) (Math.random() * 80000);
        }

        Instant startTime = Instant.now();
        bubbleSort(arr);
//        System.out.println(Arrays.toString(arr));
        Instant endTime = Instant.now();
        System.out.println("共耗時:" + Duration.between(startTime, endTime).toMillis() + " 毫秒");
    }

測試輸出

運行幾次,差不多在 13 秒左右
共耗時:14656 毫秒
共耗時:13853 毫秒

到此這篇關于java 排序算法之冒泡排序的文章就介紹到這了,更多相關java 冒泡排序內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • IDEA中如何引入spring的命名空間

    IDEA中如何引入spring的命名空間

    這篇文章主要介紹了IDEA中如何引入spring的命名空間問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Springboot Cucumber測試配置介紹詳解

    Springboot Cucumber測試配置介紹詳解

    這篇文章主要介紹了Springboot Cucumber測試配置介紹詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04
  • IntelliJ IDEA JRebel 安裝使用圖文教程(熱部署插件)

    IntelliJ IDEA JRebel 安裝使用圖文教程(熱部署插件)

    IDEA 全稱 IntelliJ IDEA,是java語言開發(fā)的集成環(huán)境,IntelliJ在業(yè)界被公認為最好的java開發(fā)工具之一。這篇文章主要介紹了IntelliJ IDEA 熱部署插件JRebel 安裝使用圖文教程,需要的朋友可以參考下
    2018-03-03
  • 詳解Java中的File文件類以及FileDescriptor文件描述類

    詳解Java中的File文件類以及FileDescriptor文件描述類

    在Java中File類可以用來新建文件和目錄對象,而FileDescriptor類則被用來表示文件或目錄的可操作性,接下來我們就來詳解Java中的File文件類以及FileDescriptor文件描述類
    2016-06-06
  • Java 如何獲取url地址文件流

    Java 如何獲取url地址文件流

    這篇文章主要介紹了Java 如何獲取url地址文件流,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • SpringBoot 2.6.x整合springfox 3.0報錯問題及解決方案

    SpringBoot 2.6.x整合springfox 3.0報錯問題及解決方案

    這篇文章主要介紹了SpringBoot 2.6.x整合springfox 3.0報錯問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 在SpringBoot中實現(xiàn)一個訂單號生成系統(tǒng)的示例代碼

    在SpringBoot中實現(xiàn)一個訂單號生成系統(tǒng)的示例代碼

    在Spring Boot中設計一個訂單號生成系統(tǒng),主要考慮到生成的訂單號需要滿足的幾個要求:唯一性、可擴展性、以及可能的業(yè)務相關性,本文給大家介紹了幾種常見的解決方案及相應的示例代碼,需要的朋友可以參考下
    2024-02-02
  • Java代理模式實例分析

    Java代理模式實例分析

    這篇文章主要介紹了Java代理模式,結合實例形式對比分析了java代理模式的使用方法與相關操作技巧,需要的朋友可以參考下
    2019-07-07
  • Mybatis輸入輸出映射及動態(tài)SQL Review

    Mybatis輸入輸出映射及動態(tài)SQL Review

    這篇文章主要介紹了Mybatis輸入輸出映射及動態(tài)SQL Review,需要的朋友可以參考下
    2017-02-02
  • SpringMVC實現(xiàn)登錄與注冊功能的詳細步驟

    SpringMVC實現(xiàn)登錄與注冊功能的詳細步驟

    本文介紹了如何通過Maven配置依賴,創(chuàng)建前端登錄和注冊頁面,并實現(xiàn)后端邏輯,詳細步驟包括配置文件、創(chuàng)建User類、配置中文過濾器及DispatcherServlet,并使用Spring?MVC和JQuery處理前端請求,需要的朋友可以參考下
    2024-11-11

最新評論

竹山县| 虹口区| 桂林市| 阿勒泰市| 白城市| 卢龙县| 麻城市| 山阳县| 德兴市| 鄢陵县| 增城市| 怀安县| 松滋市| 乳山市| 神池县| 兴国县| 大悟县| 炉霍县| 石景山区| 德格县| 马公市| 阳山县| 山阳县| 洛川县| 萨嘎县| 通海县| 淮安市| 巴彦县| 璧山县| 塔城市| 镇安县| 辽阳县| 陵川县| 靖边县| 贺州市| 洪洞县| 丘北县| 景泰县| 文山县| 肥东县| 新宾|