動畫:一篇文章快速學會基數排序

內容介紹

基數排序簡介

前面學過計數排序桶排序都是非基於比較的排序算法,它們的優點在於對必定範圍內的數據排序時能夠突破基於比較排序算法的時間複雜度O(nlogn)。java

基數排序是一種非比較型整數排序算法,基數排序的發明能夠追溯到1887年赫爾曼·何樂禮在打孔卡片製表機(Tabulation Machine)上的貢獻。git

基數排序的思想

基數排序(Radix Sort)是計數排序的擴展,它的基本思想是:將整數按位數分割成不一樣的數字,而後按每一個位數分別比較。 具體作法是:將全部待排序數值(正整數)統一爲一樣的數位長度,數位較短的數前面補零。而後從最低位開始,依次進行排序。這樣從最低位排序一直到最高位排序完成之後, 數列就變成一個有序數列。算法

基數排序動畫演示

假設有{16, 28, 19, 65, 95, 98, 81, 77, 18, 15}這10個數據。通常沒有特殊要求排序算法都是升序排序,小的在前,大的在後,效果以下: 編程

基數序分析

經過上面動畫能夠看出基數排序就是將數字按位分割,每一位進行一次計數排序,最終完成排序。數組

首先使用個位進行一次計數排序,效果以下: 微信

接着使用十位進行計數排序,效果以下: 動畫

最終排序效果以下: code

基數排序代碼編寫

public class RadixSort {
    public static void main(String[] args) {
        int[] arr = {16, 28, 19, 65, 95, 98, 81, 77, 18, 15};

        radixSort(arr);
        System.out.println("排序後: " + Arrays.toString(arr));
    }

    public static void radixSort(int[] arr) {
        // 獲取數組中最大元素
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max)
                max = arr[i];
        }

        // 按位進行計數排序
        for (int exp = 1; max/exp > 0; exp *= 10) {
            countingSort(arr, exp);
            System.out.println("radixSort = " + Arrays.toString(arr));
        }
    }

    private static void countingSort(int[] arr, int exp) {
        // 1.定義統計數組
        int[] countArr = new int[10];

        // 2.遍歷源數組,獲取每一個數據,按位放到指定位置
        for (int i = 0; i < arr.length; i++) {
            countArr[arr[i]/exp%10]++;
        }

        // 3.對輔助數組進行加工處理
        for (int i = 1; i < countArr.length; i++) {
            countArr[i] += countArr[i-1];
        }

        // 5.倒序遍歷源數組
        // 已排序數組和待排序數組同樣長
        int[] sortedArr = new int[arr.length];
        for (int i = arr.length-1; i >= 0; i--) {
            // 從源數組中取出數據
            int num = arr[i];
            sortedArr[countArr[num/exp%10] - 1] = num;
            // 輔助數組中該數據的數量減一,也就是後續相同數據放到前面一個位置
            countArr[num/exp%10]--;
        }

        // 6.將已排序的數據放到待排序的數組中
        for (int i = 0; i < sortedArr.length; i++) {
            arr[i] = sortedArr[i];
        }
    }
}

基數排序的方式

基數排序的方式能夠分爲LSDMSD兩種:blog

  1. LSD最低位優先(Least Significant Digit first)法,簡稱LSD法:先從最低(最右邊)位開始排序,再對倒數第二低位進行排序,依次重複,直到對最高位排序後便獲得一個有序序列。咱們上面的案例就是先按個位排序,再按十位排序就屬於最低位優先(LSD)
  2. MSD最高位優先(Most Significant Digit first)法,簡稱MSD法:先從最高位(最左邊)開始排序,再對第二高位進行排序,依次重複,直到對最低位排序後便獲得一個有序序列。

基數排序的複雜度

空間複雜度:每位進行排序時,須要一個長度爲10的輔助數組來統計出現的次數,還須要一個長度和待排序數組同樣的數組來存放當前當前此次計數排序的結果,因此空間複雜度爲O(n) 時間複雜度:1.獲取數組中最大元素操做次數n,2.遍歷源數組,獲取每一個數據,按位放到指定位置操做次數n,3.對輔助數組進行加工處理操做次數10,4.倒序遍歷源數組進行排序操做次數n,5.將已排序的數據放到待排序的數組中操做次數n,總的操做次數爲:4n+10,因此總的時間複雜度爲O(n)。排序

總結

基數排序(Radix Sort)是計數排序的擴展,它的基本思想是:將整數按位數分割成不一樣的數字,而後按每一個位數分別比較。 具體作法是:將全部待排序數值(正整數)統一爲一樣的數位長度,數位較短的數前面補零。而後從最低位開始,依次進行排序。這樣從最低位排序一直到最高位排序完成之後, 數列就變成一個有序數列。

基數排序的方式能夠分爲LSDMSD兩種。


原創文章和動畫製做真心不易,您的點贊就是最大的支持! 想了解更多文章請關注微信公衆號:表哥動畫學編程

相關文章
相關標籤/搜索