1. 程式人生 > >排序演算法(八)——基數排序

排序演算法(八)——基數排序

基數排序(radix sort)屬於“分配式排序”(distribution sort),又稱“桶子法”(bucket sort)或bin sort,顧名思義,它是透過鍵值的部份資訊,將要排序的元素分配至某些“桶”中,藉以達到排序的作用,基數排序法是屬於穩定性的排序。

基數排序適用於大小數字都有,且位數不同。

基數排序的演算法運作方式如下:

(1)首先根據個位數的數值,在走訪數值時將它們分配至編號0到9的桶子中,然後依次從桶中取出;

(2)再根據十位數的數值,在走訪數值時將它們分配至編號0到9的桶子中,再依次從桶中取出;

(3)依次類推,直到進行完最大數最高位的分配,取出後。完成排序功能。

基數排序的迴圈次數取決於最大樹最高位數的值。

1.使用二維陣列來實現基數排序演算法

package cn.kimtian.sort;

import java.util.Arrays;

/**
 * 基數排序
 *
 * @author kimtian
 */
public class RadixSort {
    public static void main(String[] args) {
        int arr[] = {45, 2, 67, 897, 102, 7, 508, 367, 42, 76, 34};
        RadixSort(arr);
        System.out.println(Arrays.toString(arr));
    }

    /**
     * 基數排序演算法
     * 第一次按個位排,結果如下:{2,102,42,34,45,76,67,897,367,508}
     * 第二次按十位排,結果如下:{2,102,7,508,34,42,45,67,367,76,897}
     * 第三次按百位排序:結果如下:{2,7,34,42,45,67,76,102,367,508,897}
     * 依次類推...
     */
    public static void RadixSort(int[] arr) {
        //存放陣列中最大的數字
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }
        //用於臨時儲存資料的陣列
        int[][] temp = new int[10][arr.length];
        //用於記錄在temp中相應的陣列中存放的數字的數量
        int[] counts = new int[10];

        //計算最大數字是幾位數
        int maxLength = (max + "").length();
        //根據最大長度的數決定比較次數
        for (int i = 0, n = 1; i < maxLength; i++, n *= 10) {
            //把每一個數字分別計算餘數
            for (int j = 0; j < arr.length; j++) {
                int ys = (int) (arr[j] / n % 10);
                temp[ys][counts[ys]] = arr[j];
                //記錄數量
                counts[ys]++;
            }
            int index = 0;
            //把數字取出來
            for (int g = 0; g < counts.length; g++) {
                //記錄陣列中資料的值不為0,代表有資料
                if (counts[g] != 0) {
                    for (int z = 0; z < counts[g]; z++) {
                        //取出元素放入原來陣列
                        arr[index] = temp[g][z];
                        index++;
                    }
                }
                //把數量置為0
                counts[g] = 0;
            }
        }

    }
}

2.使用佇列陣列來實現基數排序演算法

/**                                                                                            
 * 基數排序佇列實現                                                                                    
 */                                                                                            
public static void RadixSort2(int[] arr) {                                                     
    //存放陣列中最大的數字                                                                               
    int max = Integer.MIN_VALUE;                                                               
    for (int i = 0; i < arr.length; i++) {                                                     
        if (arr[i] > max) {                                                                    
            max = arr[i];                                                                      
        }                                                                                      
    }                                                                                          
    //用於臨時儲存資料的佇列陣列                                                                            
    MyQueue[] temp = new MyQueue[10];                                                          
    //為佇列陣列賦值                                                                                  
    for (int i = 0; i < temp.length; i++) {                                                    
        temp[i] = new MyQueue();                                                               
    }                                                                                          
                                                                                               
    //計算最大數字是幾位數                                                                               
    int maxLength = (max + "").length();                                                       
    //根據最大長度的數決定比較次數                                                                           
    for (int i = 0, n = 1; i < maxLength; i++, n *= 10) {                                      
        //把每一個數字分別計算餘數                                                                         
        for (int j = 0; j < arr.length; j++) {                                                 
            int ys = (int) (arr[j] / n % 10);                                                  
            temp[ys].addQueue(arr[j]);                                                         
        }                                                                                      
        int index = 0;                                                                         
        //把數字取出來                                                                               
        for (int z = 0; z < temp.length; z++) {                                                
            //當前遍歷的佇列不為空,則迴圈取                                                                  
            while (!temp[z].isQueueEmpty()) {                                                  
                arr[index] = (int) temp[z].pollQueue();                                        
                //記錄下一個位置                                                                      
                index++;                                                                       
            }                                                                                  
        }                                                                                      
    }                                                                                          
}