引言
本篇是排序算法的最後一篇,基數排序,桶排序的升級版。
1、算法步驟
1、首先對一組數據按照個位上的數字進行桶排序
2、然後對這組數據繼續按照十位上的數字進行桶排序
3、依次循環至這組數據的最大數位置上,排序就完成了。
2、時間複雜度
平均時間複雜度O(n + k)
3、算法實現
public class RadixSort {
public static void main(String[] args) {
int[] numbers = {12,2,24,30,6,16};
int[] result = RadixSort.sort(numbers);
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < result.length; i++) {
stringBuffer.append(result[i] + " ");
}
System.out.println(stringBuffer.toString());
}
public static int[] sort(int[] numbers){
int[] needSort = Arrays.copyOf(numbers, numbers.length);
//獲取最大數的位數
int maxLength = getMaxLength(needSort);
//根據位數依次排序
return radixSort(needSort, maxLength);
}
public static int getMaxLength(int[] arg){
//獲取最大的數
int maxValue = arg[0];
for (int i = 1; i < arg.length; i++) {
if(maxValue < arg[i]){
maxValue = arg[i];
}
}
//獲取最大數位數
if(maxValue == 0){
return 1;
}
int maxLength = 0;
for (long temp = maxValue; temp != 0; temp /= 10) {
maxLength++;
}
return maxLength;
}
public static int[] radixSort(int[] arg,int maxLength){
//位數
int dev = 1;
//10進制
int hex = 10;
for (int i = 0; i < maxLength; i++,dev *= 10,hex *= 10) {
// 考慮負數的情況,這裏擴展一倍隊列數,其中 [0-9]對應負數,[10-19]對應正數 (bucket + 10)
int[][] counter = new int[hex * 2][0];
for (int j = 0; j < arg.length; j++) {
int bucket = (arg[j] % hex) / dev + hex;
counter[bucket] = arrayAppend(counter[bucket],arg[j]);
}
int length = 0;
for (int[] bucket : counter) {
for (int value : bucket){
arg[length++] = value;
}
}
}
return arg;
}
private static int[] arrayAppend(int[] arr, int value) {
arr = Arrays.copyOf(arr, arr.length + 1);
arr[arr.length - 1] = value;
return arr;
}
}
4、總結
計數排序中每個桶只存儲單一數值,有很多空桶浪費了;桶排序中,每個桶存儲一定範圍的數值,每個桶中的數據仍需再排序;基數排序是根據鍵值的每位數字來分配桶。
結束語
排序算法到此結束,現在入職新公司,在熟悉業務和代碼中,後面有時間刷LeetCode的時候會再進行總結。