排序演算法(八)——基數排序
阿新 • • 發佈:2019-01-14
基數排序(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++; } } } }