Skip navigation

2015-07-07

基数ソート

基数ソートのJava版です。 各桁(十進法)について、分布数え(バケット)ソートを行います。 入力されたn個と同サイズのメモリが確保され、桁ごとにメモリコピーが発生します。 入力データが少ない場合は、とても高速です。

package com.clustack;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class RadixSort {

    public static Integer[] sort(Integer[] arr, boolean desc) {
        int n = arr.length;

        int i;
        Integer maxValue = null;
        int exp = 1; // digit
        Integer[] tmp = new Integer[n];
        Integer[] hists = new Integer[10];

        while (true) {
            Arrays.fill(hists, 0);

            if (maxValue == null) { // for exit condition
                maxValue = arr[0];
                for (int ar : arr) {
                    if (ar > maxValue)
                        maxValue = ar;
                    hists[(ar / exp) % 10]++; // frequency distribution of digit 0..9
                }
            } else {
                for (int ar : arr)
                    hists[(ar / exp) % 10]++; // frequency distribution of digit 0..9
            }

            if (desc) {
                for (i = 9; i > 0; i--)
                    hists[i - 1] += hists[i]; // cumulative frequency distribution
            } else { // ascending order
                for (i = 1; i < 10; i++)
                    hists[i] += hists[i - 1]; // cumulative frequency distribution
            }
            for (i = n - 1; i >= 0; i--)
                tmp[--hists[(arr[i] / exp) % 10]] = arr[i];

            exp *= 10; // next digit
            if (maxValue / exp <= 0)
                return tmp;
            System.arraycopy(tmp, 0, arr, 0, n); // copy to results array
        }
    }

    public static void main(String[] args) {
        List<Integer> lists = new ArrayList<>();
        for (int i = 0; i < 100; i++)
            lists.add(i);
        Collections.shuffle(lists);
        System.out.println("Unsorted:" + lists);
        Integer[] results = RadixSort.sort(lists.toArray(new Integer[0]), false);
        System.out.println("Sorted(asc): " + Arrays.asList(results));

        System.out.println("\nUnsorted:" + lists);
        results = RadixSort.sort(lists.toArray(new Integer[0]), true);
        System.out.println("Sorted(desc): " + Arrays.asList(results));
    }
}