iT邦幫忙

2024 iThome 鐵人賽

0

基數排序

實現方式是:將整數按位數切割成不同的數字,然後按每個位數分別比較,基數排序法屬於穩定性的排序,同時是對傳統桶排序的擴展,速度很快,也是經典空間換時間的方式,佔用記憶體很大,當要對海量數據進行時容易造成OutOfMemoryError。

基本概念

  1. 將所有待比較數值統一為同樣的位數長度,位數較短的數前面補零。
  2. 從最低位開始,依次進行一次排序。
  3. 這樣從最低位排序一直到最高位排序完成以後,數列就變成一個有序序列。
  4. 要做多少輪排序取決於所有元素中最高位數元素的位數。

程式範例試做:

import java.util.Arrays;

public class Alex1013_1 {
    public static void main(String[] args) {
        int arr[] = {601,  73, 2,  465,  371,  229};
        Alex1013_1(arr);
    }

    public static void Alex1013_1(int[] arr) {
        // 得到陣列中最大的數的位數
        int max = arr[0];
        for(int i = 1; i < arr.length; i++) {
            if(arr[i] > max) {
                max = arr[i];
            }
        }

        int maxLength = (max + "").length();

        // 定義一個二維陣列,表示10個桶,每個桶就是一個一維陣列
        // 1. 二維陣列包含10個一維陣列
        // 2. 為了防止在放入數的時候,數據溢出,則每個一維陣列大小定為arr.length => 空間換時間
        int[][] bucket = new int[10][arr.length];

        // 定義為一個一維陣列,紀錄各個桶每次放入的數據個數
        int[] bucketElementCounts = new int[10];

        // 針對每個元素的各位數進行排序處理
        for(int i = 0 , n = 1; i < maxLength; i++, n *= 10) {
            for(int j = 0; j < arr.length; j++) {
                // 取出每個元素的的對應位數的值
                int digitOfElement = arr[j] / n % 10;
                // 放入到對應的桶中
                bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j];
                bucketElementCounts[digitOfElement]++ ;
            }

            // 遍歷每個桶, 並將桶中數據放入到原陣列
            int index = 0;
            for(int k = 0; k < bucketElementCounts.length; k++) {
                // 如果桶中有數據才放入到原陣列
                if(bucketElementCounts[k] != 0) {
                    // 遍歷該桶 放入
                    for(int l = 0; l < bucketElementCounts[k]; l++) {
                        arr[index++] = bucket[k][l];
                    }
                }
                // 每輪處理後要將 bucketElementCounts 清零
                bucketElementCounts[k] = 0;
            }
            System.out.println("第 "+(i+1)+" 輪排序後為:"+Arrays.toString(arr));
        }
    }
}

程式執行結果:

第 1 輪排序後為:[601, 371, 2, 73, 465, 229]
第 2 輪排序後為:[601, 2, 229, 465, 371, 73]
第 3 輪排序後為:[2, 73, 229, 371, 465, 601]

基數排序法的效率在於它不直接比較數字,而是基於數字的位數進行排序,特別適合處理範圍固定且元素較多的情況。


上一篇
Java程式-合併排序法
下一篇
Java程式-堆積排序法
系列文
自學Java物件導向程式語言30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言