一、動圖演
二、思路分析
基數排序第i趟將待排數組里的每個數的i位數放到tempj(j=1-10)隊列中,然后再從這十個隊列中取出數據,重新放到原數組里,直到i大於待排數的最大位數。
1.數組里的數最大位數是n位,就需要排n趟,例如數組里最大的數是3位數,則需要排3趟。
2.若數組里共有m個數,則需要十個長度為m的數組tempj(j=0-9)用來暫存i位上數為j的數,例如,第1趟,各位數為0的會被分配到temp0數組里,各位數為1的會被分配到temp1數組里......
3.分配結束后,再依次從tempj數組中取出數據,遵循先進先進原則,例如對數組{1,11,2,44,4},進行第1趟分配后,temp1={1,11},temp2={2},temp4={44,4},依次取出元素后{1,11,2,44,4},第一趟結束
4.循環到n趟后結束,排序完成
根據思路分析,每一趟的執行流程如下圖所示:
通過基數排序對數組{53, 3, 542, 748, 14, 214, 154, 63, 616}:
三、負雜度分析
1. 時間復雜度:
每一次關鍵字的桶分配都需要O(n)的時間復雜度,而且分配之后得到新的關鍵字序列又需要O(n)的時間復雜度。
假如待排數據可以分為d個關鍵字,則基數排序的時間復雜度將是O(d*2n) ,當然d要遠遠小於n,因此基本上還是線性級別的。
系數2可以省略,且無論數組是否有序,都需要從個位排到最大位數,所以時間復雜度始終為O(d*n) 。其中,n是數組長度,d是最大位數。
2. 空間復雜度:
基數排序的空間復雜度為O(n+k),其中k為桶的數量,需要分配n個數。
四、Java 代碼如下
import java.util.Arrays; public class Main { public static void main(String[] args) { int[] arr = new int[]{10,6,3,8,33,27,66,9,7,88}; radixSort(arr); } private static void radixSort(int[] arr) { //求出待排數的最大數
int maxLength=0; for (int i = 0; i < arr.length; i++) { if(maxLength<arr[i]) maxLength = arr[i]; } //根據最大數求最大長度
maxLength = (maxLength+"").length(); //用於暫存數據的數組
int[][] temp = new int[10][arr.length]; //用於記錄temp數組中每個桶內存的數據的數量
int[] counts = new int[10]; //用於記錄每個數的i位數
int num = 0; //用於取的元素需要放的位置
int index = 0; //根據最大長度決定排序的次數
for (int i = 0,n=1; i < maxLength; i++,n*=10) { for (int j = 0; j < arr.length; j++) { num = arr[j]/n%10; temp[num][counts[num]] = arr[j]; counts[num]++; } //從temp中取元素重新放到arr數組中
for (int j = 0; j < counts.length; j++) { for (int j2 = 0; j2 < counts[j]; j2++) { arr[index] = temp[j][j2]; index++; } counts[j]=0; } index=0; } System.out.println(Arrays.toString(arr)); } }