基數排序

基數排序

基於桶式排序,將要排序的數字一位一位的比較,經歷多次桶式排序,得出最終的序列
如果要排序的元素可以分成多位,並且每一位都在一個固定的範圍內,則可以用這種排序方法,如對10進制數字的排序

有數字23,35,9,73,3,314,11,1234,5,可以看出來,每一位數字的取值範圍都是0到9,所以我們可以用10個桶來進行排序,分別編號0到9。

①第一遍排序,按照最低位數字將各個數字存入桶中:

桶號 0 1 2 3 4 5 6 7 8 9
存放數字 11 23,73,3 314,1234 35,5 9

按照桶的序號將所有的數字倒出來,對於一個桶內有多個數字的情況,我們按照先進先出的原則倒出數字:

桶的倒出順序 數字隊列
9 9
8 9
7 9
6 9
5 9,35,5
4 9,35,5,314,1234
3 9,35,5,314,1234,23,73,3
2 9,35,5,314,1234,23,73,3
1 9,35,5,314,1234,23,73,3,11
0 9,35,5,314,1234,23,73,3,11

我們可以看大第一遍排序好的數字還是很亂的,可能還不能基數排序的妙處,不急,下面我們進行第二次排序

②第二遍排序,將第一次排好的序列9,35,5,314,1234,23,73,3,11,按照第二位的數字存入桶中(只有一位的數第二位爲0):

桶號 0 1 2 3 4 5 6 7 8 9
存放數字 9,5,3 314,11 23 35,1234 73

按照桶的序號將所有的數字倒出來,對於一個桶內有多個數字的情況,我們按照先進先出的原則倒出數字:

桶的倒出順序 數字隊列
9
8
7 73
6 73
5 73
4 73
3 73,35,1234
2 73,35,1234,23
1 73,35,1234,23,314,11
0 73,35,1234,23,314,11,9,5,3

我們發現,第二遍之後,有些數字好像已經排序好了,經過兩次排序,或許你已經能看出來一些基數排序的原理了,下面我們進行第三遍排序

③第三遍排序,將第二次排好的序列73,35,1234,23,314,11,9,5,3,按照第三位的數字存入桶中(只有兩位的數第三位爲0):

桶號 0 1 2 3 4 5 6 7 8 9
存放數字 73,35,23,11,9,5,3 1234 314

按照桶的序號將所有的數字倒出來,對於一個桶內有多個數字的情況,我們按照先進先出的原則倒出數字:

桶的倒出順序 數字隊列
9
8
7
6
5
4
3 314
2 314,1234
1 314,1234
0 314,1234,73,35,23,11,9,5,3

第三遍排序結束,相信你已經看出來基數排序到底是個什麼東西了,如果你還不懂,後面會有一個flash,清晰明瞭的一步一步爲你分解基數排序,在這之前,讓我們先勤勤懇懇的把第四遍,也是最後一遍排序完成

④第四遍排序,將第三次排好的序列314,1234,73,35,23,11,9,5,3,按照第四位的數字存入桶中(只有三位的數第四位爲0):

桶號 0 1 2 3 4 5 6 7 8 9
存放數字 314,73,35,23,11,9,5,3 1234

按照桶的序號將所有的數字倒出來,對於一個桶內有多個數字的情況,我們按照先進先出的原則倒出數字:

桶的倒出順序 數字隊列
9
8
7
6
5
4
3
2
1 1234
0 1234,314,73,35,23,11,9,5,3

至此,我們終於完成了排序。

代碼示例

/**
 * 基數排序
 * 
 * @author yangpeng
 *
 */
public class RadixSortDemo {

    public static void main(String[] args) {
        int[] a = { 2, 7, 8, 3, 10, 62, 92, 0, 5, 4 };
        System.out.println("初始序列:" + Arrays.toString(a));
        RadixSort(a, getMaxWei(a));
        System.out.println("最後:" + Arrays.toString(a));
    }

    /**
     * 
     * @param a
     *            需要排序的數組
     * @param d
     *            數組 的最大位數
     */
    public static void RadixSort(int[] a, int d) {

        // 二維數組 temp用來保存當前的排序的數字
        // 第一維 10 表示一共有10個桶
        // 第二維a.length 表示每個桶最多可能存放a.length個數字
        int[][] temp = new int[10][a.length + 1];
        int[] order = new int[10];
        for (int pos = 1; pos <= d; pos++) {
            // 將數據分配到每個桶中
            for (int i = 0; i < order.length; i++) {
                int row = getMaxPos(a[i], pos);// 第一個桶
                int col = ++order[row];// 桶的數據+1;
                temp[row][col] = a[i];

            }

            for (int i = 0; i < temp.length; i++) {
                System.out.print(i + "個桶 ");
                for (int j = 0; j < temp[i].length; j++) {
                    System.out.print(temp[i][j] + "  ");
                }
                System.out.print("order:" + order[i]);
                System.out.println();

            }

            int k = 0;
            for (int i = 0; i < order.length; i++) {
                if (order[i] != 0) {
                    // 存在相應的值
                    for (int j = 1; j <= order[i]; j++) {
                        a[k] = temp[i][j];
                        k++;
                    }
                }
                order[i] = 0;
            }
            System.out.println(pos + "最後:" + Arrays.toString(a));
        }
    }

    /**
     * 求當前數 的在指定位置的餘數
     * 
     * @param num
     *            帶求的數
     * @param pos
     *            位數 1表示個位, 2表示十位, 3表示百位
     * @return 返回餘數
     */
    public static int getMaxPos(int num, int pos) {
        int temp = 1;
        for (int i = 0; i < pos - 1; i++) {
            temp *= 10;
        }
        return (num / temp) % 10;
    }

    /**
     * 求數組的位數
     * 
     * @param a
     *            帶求的數組
     * @return 返回數組的最大位數
     */
    public static int getMaxWei(int[] a) {
        int max = a[0];
        // 先找到a數組的最大值
        for (int i = 1; i < a.length; i++) {
            if (a[i] > max) {
                max = a[i];
            }
        }

        int temp = 1, d = 1;
        while (true) {
            temp *= 10;
            if (max / temp != 0) {
                d++;
            } else {
                break;
            }
        }
        return d;
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章