1. 程式人生 > >基數排序(java實現)

基數排序(java實現)

  • 思路
  • 演算法屬性
  • 程式碼

 

思路

將所有待比較數值(正整數)統一為同樣的數位長度,數位較短的數前面補零。然後,從最低位開始,依次進行一次排序。這樣從最低位排序一直到最高位排序完成以後,數列就變成一個有序序列。

  • 將所有待比較數值(正整數)統一為同樣的數位長度,數位較短的數前面補零。
  • 從最低位開始,依次進行一次排序。
  • 這樣從最低位排序一直到最高位排序完成以後, 數列就變成一個有序序列。

演算法屬性

參考文章:【點我】

時間複雜度:基數排序中r為基數,d為位數。時間複雜度為O(d(n+r))

空間複雜度:對於任何位數上的基數進行“裝桶”操作時,都需要n+r

個臨時空間。

穩定性:相同的數字並不需要交換位置。所以基數排序是穩定的演算法。

排序型別 時間複雜度(平均) 時間複雜度(最壞) 時間複雜度(最好) 空間複雜度 穩定性 複雜性
交換排序 O(d(n+r)) O(d(n+r)) O(d(n+r)) O(n+r) 穩定 較複雜

程式碼

public static void main(String[] args) {
	int[] a = { 1, 5, 6, 3, 2, 4 };
	digitSort(a, a.length);
	print(a);// 自定義輸出陣列
}

public static int maxBit(int[] inputList) {// 返回陣列中最大的位數(如獲取123的1所在的位數,結果返回3)
	int maxData = inputList[0];
	for (int i = 0; i < inputList.length; i++) {
		if (inputList[i] > maxData)
			maxData = inputList[i];
	}
	int bitsNum = 0;
	while (maxData > 0) {
		bitsNum++;
		maxData /= 10;
	}
	return bitsNum;
}

public static int digit(int num, int d) {// 返回數的第d位的數字(如123第2位的數字是2)
	int pow = 1;
	while (--d > 0) {
		pow *= 10;
	}
	return num / pow % 10;
}

public static void digitSort(int[] inputList, int n) {
	int[] bucket = new int[n];// 臨時陣列,來儲存排序過程中的數字
	int[] count = new int[10];// 位計數器,當前位是0的有多少個,是1的有多少個...
	for (int d = 1; d <= maxBit(inputList); d++) {// 從低位往高位迴圈
		for (int i = 1; i < 10; i++) {
			count[i] = 0;// 計數器清零
		}
		for (int i = 0; i < n; i++) {// 統計各個桶中的個數
			count[digit(inputList[i], d)]++;
		}
		for (int i = 1; i < 10; i++) {// count[i]表示第i個桶的右邊界索引
			count[i] += count[i - 1];
		}
		// 這裡只能從陣列後往前迴圈,因為排序時還需保持以前的已排序好的順序,不應該打亂原來已排好的序
		for (int i = n - 1; i >= 0; i--) {
			int k = digit(inputList[i], d);// 求出關鍵碼的第k位的數字, 例如:576的第3位是5
			bucket[count[k] - 1] = inputList[i];// 放入對應的桶中,count[j]-1是第j個桶的右邊界索引
			count[k]--;// 對應桶的裝入資料索引減一
		}
		for (int i = 0; i < n; i++) {// 陣列放到inputList中
			inputList[i] = bucket[i];
		}
	}
}