1. 程式人生 > >演算法-Java-0001-氣泡排序

演算法-Java-0001-氣泡排序

簡介

我們通常所說的排序演算法往往指的是內部排序演算法,即資料記錄在記憶體中進行排序。

  排序演算法大體可分為兩種:

  • 比較排序,時間複雜度O(nlogn) ~ O(n^2),主要有:氣泡排序,選擇排序,插入排序,歸併排序,堆排序,快速排序等。
  • 非比較排序,時間複雜度可以達到O(n),主要有:計數排序,基數排序,桶排序等。

如下圖
這裡寫圖片描述

  有一點我們很容易忽略的是排序演算法的穩定性(騰訊校招2016筆試題曾考過)。

  排序演算法穩定性的簡單形式化定義為:如果Ai = Aj,排序前Ai在Aj之前,排序後Ai還在Aj之前,則稱這種排序演算法是穩定的。通俗地講就是保證排序前後兩個相等的數的相對順序不變。

  對於不穩定的排序演算法,只要舉出一個例項,即可說明它的不穩定性;而對於穩定的排序演算法,必須對演算法進行分析從而得到穩定的特性。需要注意的是,排序演算法是否為穩定的是由具體演算法決定的,不穩定的演算法在某種條件下可以變為穩定的演算法,而穩定的演算法在某種條件下也可以變為不穩定的演算法。

  例如,對於氣泡排序,原本是穩定的排序演算法,如果將記錄交換的條件改成A[i] >= A[i + 1],則兩個相等的記錄就會交換位置,從而變成不穩定的排序演算法。

  其次,說一下排序演算法穩定性的好處。排序演算法如果是穩定的,那麼從一個鍵上排序,然後再從另一個鍵上排序,前一個鍵排序的結果可以為後一個鍵排序所用。基數排序就是這樣,先按低位排序,逐次按高位排序,低位排序後元素的順序在高位也相同時是不會改變的。

以上內容我不是很理解。

本篇介紹其中之一的氣泡排序,其他排序會在後續章節介紹。

分析

氣泡排序是一種極其簡單且好理解的排序演算法,也是大學時期學習的第一個排序演算法。它重複地走訪過要排序的元素,依次比較相鄰兩個元素,如果他們的順序錯誤就把他們調換過來,直到沒有元素再需要交換,排序完成。這個演算法的名字由來是因為越小(或越大)的元素會經由交換慢慢“浮”到數列的頂端-故得名“冒泡”。

氣泡排序演算法的運作如下:

  • 比較相鄰的元素,如果前一個比後一個大,就把它們兩個調換位置。
  • 對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。這步做完後,最後的元素會是最大的數。
  • 針對所有的元素重複以上的步驟,除了最後一個。
  • 持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。
  • 由於它的簡潔,氣泡排序通常被用來對於程式設計入門的學生介紹演算法的概念。

視覺圖效果

這裡寫圖片描述

程式碼實現

private static final Logger logger = LoggerFactory.getLogger(BubbleSort.class);

public static int[] bubbleSort(int[] arrayA){
    if(null == arrayA || arrayA.length <= 0) return null;

    logger.info("原始陣列:{}" ,Arrays.toString(arrayA));
    for (int i = 0; i < arrayA.length-1; i++) {
        for (int j = 0; j < arrayA.length - 1 - i; j++) {
            if (arrayA[j] > arrayA[j+1]) {
                logger.info("比較{}跟{},{}>{},交換位置", arrayA[j], arrayA[j+1], arrayA[j], arrayA[j+1]);
                SortUtils.swap(arrayA, j, j+1);
                logger.info("交換後陣列:{}", Arrays.toString(arrayA));
            }else{
                logger.info("比較{}跟{},{}<{},不交換位置 , 陣列:{}", arrayA[j], arrayA[j+1], arrayA[j], arrayA[j+1], Arrays.toString(arrayA));
            }
        }
//      logger.info("第{}輪查找出來第{}小的數{}", (i+1), (i+1) ,arrayA[i]);
    }
    return arrayA;
}

/**
 * @description <p>元素交換</p>
 * @param
 * @return No such property: code for class: Script1
 * @author heshiyuan 
 * @date 2018/8/27 20:49 
 * @email [email protected]
 * @github https://github.com/shiyuan2he.git
 * Copyright (c) 2018 [email protected] All rights reserved
 */
public static void swap(int[] array, int i, int j){
    int temp = array[j];
    array[j] = array[i];
    array[i] = temp;
}

測試

測試用例

  • 100以內連續的陣列-升序
  • 100以內連續的陣列-降序
  • 100以內隨機的陣列-亂序

測試程式碼

/**
 * @author heshiyuan
 * @description <p></p>
 * @path java/com.hsy.algorithm.s0001
 * @date 2018/8/27 16:43
 * @github http://github.com/shiyuan2he
 * @email [email protected]
 * Copyright (c) 2018 [email protected] All rights reserved.
 * @price ¥5    微信:hewei1109
 */
public class BubbleSortTest {
    private static final Logger logger = LoggerFactory.getLogger(BubbleSortTest.class);

    @Test
    public void bubbleSort() {
        logger.info("最終結果:{}", BubbleSort.bubbleSort(SortUtils.generateNumberByASC(100)));
        logger.info("最終結果:{}", BubbleSort.bubbleSort(SortUtils.generateNumberByDesc(100)));
        logger.info("最終結果:{}", BubbleSort.bubbleSort(SortUtils.generateRandomNumber(100)));
    }
}

public static int[] generateRandomNumber(int length){
    int[] randomArray = new int[length];
    for(int i=0;i<length;i++){
        randomArray[i] = new Random().nextInt(length);
    }
    return randomArray;
}
/**
 * @description <p>生成length以內升序陣列</p>
 * @param length 傳遞進來的陣列長度
 * @return No such property: code for class: Script1
 * @author heshiyuan
 * @date 2018/8/27 22:30
 * @email [email protected]
 * @github https://github.com/shiyuan2he.git
 * Copyright (c) 2018 [email protected] All rights reserved
 */
public static int[] generateNumberByASC(int length){
    int[] randomArray = new int[length];
    for(int i=0;i<length;i++){
        randomArray[i] = i+1;
    }
    return randomArray;
}

/**
 * @description <p>生成length以內降序陣列</p>
 * @param length 傳遞進來的陣列長度
 * @return No such property: code for class: Script1
 * @author heshiyuan
 * @date 2018/8/27 22:30
 * @email [email protected]
 * @github https://github.com/shiyuan2he.git
 * Copyright (c) 2018 [email protected] All rights reserved
 */
public static int[] generateNumberByDesc(int length){
    int[] randomArray = new int[length];
    int value = 1;
    for(int i=length;i>0;i--){
        randomArray[i-1] = value;
        value ++;
    }
    return randomArray;
}

測試結果

硬體環境

i5 四核 8G記憶體

  1. 100以內連續的陣列-升序
2018-08-29 08:54:50.950 - INFO [           main] com.hsy.algorithm.s0001.BubbleSort       : 原始陣列:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
2018-08-29 08:54:50.964 - INFO [           main] com.hsy.algorithm.s0001.BubbleSort       : 耗時:8 ms
2018-08-29 08:54:50.964 - INFO [           main] com.hsy.algorithm.s0001.BubbleSortTest   : 最終結果:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
  1. 100以內連續的陣列-降序
2018-08-29 08:57:14.457 - INFO [           main] com.hsy.algorithm.s0001.BubbleSort       : 原始陣列:[100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
2018-08-29 08:57:14.463 - INFO [           main] com.hsy.algorithm.s0001.BubbleSort       : 耗時:1 ms
2018-08-29 08:57:14.463 - INFO [           main] com.hsy.algorithm.s0001.BubbleSortTest   : 最終結果:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
  1. 100以內隨機的陣列-亂序
2018-08-29 08:58:10.116 - INFO [           main] com.hsy.algorithm.s0001.BubbleSort       : 原始陣列:[60, 20, 86, 94, 80, 74, 25, 98, 50, 70, 49, 59, 91, 83, 45, 9, 20, 52, 77, 44, 16, 10, 70, 29, 3, 27, 50, 66, 9, 19, 32, 86, 52, 27, 77, 9, 65, 87, 83, 77, 68, 17, 82, 3, 24, 67, 91, 38, 67, 4, 46, 25, 16, 65, 64, 28, 95, 77, 81, 78, 79, 92, 81, 76, 4, 7, 34, 22, 36, 78, 43, 84, 65, 11, 20, 76, 18, 25, 71, 46, 55, 82, 80, 23, 33, 53, 35, 29, 29, 7, 82, 34, 39, 19, 78, 29, 76, 22, 14, 53]
2018-08-29 08:58:10.119 - INFO [           main] com.hsy.algorithm.s0001.BubbleSort       : 耗時:1 ms
2018-08-29 08:58:10.120 - INFO [           main] com.hsy.algorithm.s0001.BubbleSortTest   : 最終結果:[3, 3, 4, 4, 7, 7, 9, 9, 9, 10, 11, 14, 16, 16, 17, 18, 19, 19, 20, 20, 20, 22, 22, 23, 24, 25, 25, 25, 27, 27, 28, 29, 29, 29, 29, 32, 33, 34, 34, 35, 36, 38, 39, 43, 44, 45, 46, 46, 49, 50, 50, 52, 52, 53, 53, 55, 59, 60, 64, 65, 65, 65, 66, 67, 67, 68, 70, 70, 71, 74, 76, 76, 76, 77, 77, 77, 77, 78, 78, 78, 79, 80, 80, 81, 81, 82, 82, 82, 83, 83, 84, 86, 86, 87, 91, 91, 92, 94, 95, 98]

總結

上面三種測試用例效率不足以作為參考,因為我在測試期間,那種測試用例放第一個,哪種測試用耗時就會長,此種現象後續剖析。

相關推薦

演算法-Java-0001-氣泡排序

簡介 我們通常所說的排序演算法往往指的是內部排序演算法,即資料記錄在記憶體中進行排序。   排序演算法大體可分為兩種: 比較排序,時間複雜度O(nlogn) ~ O(n^2),主要有:氣泡排序,選擇排序,插入排序,歸併排序,堆排序,快速排序等。 非比較排

演算法 -- Java實現氣泡排序(圖解 + 程式碼實現)

排序思想: 相鄰元素兩兩比較,大的往後放,第一次完畢,最大值出現在了最大索引處(每比較完一趟,就選出一個最大值放到了後面),同理繼續可以得到一個排好序的陣列 排序圖解: 排序規

3. 排序通常有多種演算法,如氣泡排序、插入排序、選擇排序、希爾排序、歸併排序、快速排序,請選擇任意2種用java實現 [分值:20] 您的回答:(空) (簡答題需要人工評分)

3. 排序通常有多種演算法,如氣泡排序、插入排序、選擇排序、希爾排序、歸併排序、快速排序,請選擇任意2種用java實現  [分值:20] 您的回答:(空)  (簡答題需要人工評分) package com.interview; /** * 各種排序演算法 */

Java演算法實現之氣泡排序及優化

氣泡排序,是一種很簡單的排序演算法。原理就不過多介紹了,直接入手demo。 需求:輸入一組資料,用氣泡排序進行排序。 先用最直接的方法進行排序,程式碼如下: //對一組數進行氣泡排序 public class Bubble01 { public static void m

JAVA 複習氣泡排序 , 遞迴演算法

使用氣泡排序,首先我們要知道,外層n-1,內層n-i-1,外層是表示迴圈的次數,內層表示迴圈比較,比較的方式是用賦值的方式進行比較的,用我們比較通俗的話來說,兩兩相比,大者後移。氣泡排序和遞迴是基本演算

java氣泡排序、選擇排序、快速排序、插入排序、java8排序

package cn.com.javatest.sort; import org.apache.commons.lang3.StringUtils; /** * 常用排序方法 * * @author: Rodge * @time: 2018年10月4日 下午5:16:22 * @ve

排序演算法(五):氣泡排序(Bubble Sort)

基本思想: 在要排序的一組數中,對當前還未排好序的範圍內的全部數,自上而下對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉,較小的往上冒。即:每當兩相鄰的數比較後發現它們的排序與排序要求相反時,就將它們互換。 氣泡排序的示例:   演算法的實現: public v

Java氣泡排序

氣泡排序:  package com.wochat.controller; public class MainClass { public static void main(String[] args) { int score[] = {67, 75, 69

Java 實現氣泡排序法對陣列進行排序

氣泡排序是交換排序中的一種簡單的排序方法。它的基本思想是對所有相鄰記錄的關鍵字值進行比較,如果是逆序(a[j]>a[j+1]),則將其交換,最終達到有序化。  public class BubbleSort { public void sortArray() { int

排序演算法之一:氣泡排序&選擇排序&插入排序

1.氣泡排序 原理:比較兩個相鄰的元素,將值大的元素交換至右端。 複雜度:O(n*n) 思路:依次比較相鄰的兩個數,將小數放在前面,大數放在後面。即在第一趟:首先比較第1個和第2個數,將小數放前,大數放後。然後比較第2個數和第3個數,將小數放前,大數放後,如此繼續,直至比較最後兩個數,將

Java——用Java實現氣泡排序,選擇排序,快速排序和二分查詢

在學習C語言時,就有講過這三個排序演算法和二分查詢的演算法。 以下是用Java來實現氣泡排序(Bubble Sort)演算法,選擇排序(Selection Sort),快速排序(Quick Sort)和二分查詢(Binary Search) package pra_07;

Java——實現氣泡排序,選擇排序,快速排序和二分查詢

在學習C語言時,對排序演算法和二分查詢有一定的理解並進行了實現。 不過打算用Java重新實現一下氣泡排序(Bubble Sort),選擇排序(Selection Sort),快速排序(Quick Sort)和二分查詢(binary_search)。 package pra

排序演算法1——圖解氣泡排序及其實現(三種方法,基於模板及函式指標)

排序演算法1——圖解氣泡排序及其實現(三種方法,基於模板及函式指標) 排序演算法2——圖解簡單選擇排序及其實現 排序演算法3——圖解直接插入排序以及折半(二分)插入排序及其實現 排序演算法4——圖解希爾排序及其實現 排序演算法5——圖解堆排序及其實現 排序演算法6——圖解歸併排序及其遞迴與非

java實現氣泡排序和選擇排序

氣泡排序:依次比較兩個相鄰的元素,將值大的元素交換至右端,一輪比較過後,最大的元素在最右端。 public class BubbleSort { public static void main(String[] args) { int[] arr

Java氣泡排序 | 二分查詢

1 public static int[] bubbleSort(int[] intArr) { 2 if (intArr == null) 3 return null; // 當傳進來的陣列為null時返回null 4 int len

java實現氣泡排序

package 演算法基礎; /** * @author 作者徐子淵 * @version 建立時間:2018年11月7日 下午3:58:50 * 類說明 */ public class Maopaoa

演算法---JAVA實現堆排序(大頂堆)

堆排序是一種樹形選擇排序方法,它的特點是:在排序的過程中,將array[0,...,n-1]看成是一顆完全二叉樹的順序儲存結構,利用完全二叉樹中雙親節點和孩子結點之間的內在關係,在當前無序區中選擇關鍵字最大(最小)的元素。 1. 若array[0,...,n-1]表示一顆完

java陣列氣泡排序

public class BubbleSort { /** * N個數字要排序完成,總共進行N-1趟排序,每i趟的排序次數為(N-i)次,所以可以用雙重迴圈語句,外層控制迴圈多少趟,內層控制每一趟的迴圈次數。 * @param args */ pu

排序演算法入門之氣泡排序

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!                在開發中,對一組資料進行有序地排列是經常需要做的事情,所以掌握幾種甚至更多的排序演算法是絕對有必要的本文章介紹的是排序演算法中較簡單的一種演算法:氣泡排序題外話

Java語言氣泡排序

首先我們定義一個數組 int[] array = { 11, 55, 22, 53, 87, 13, 66, 90 }; 陣列下表為0~7,共8位數 首先我們對array[0]與array[1]進行比較,如果array[0]>array[1],那麼大的