计数器排序的时间复杂度是O(n),辅助空间为O(n),这个是典型的用空间换时间的方法。
下面的算法导论的经典接法:
package sort;
import java.util.Scanner;
public class CountSort {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
int a[] = new int[6];
for (int i = 0; i <= 5; i++)
a[i] = reader.nextInt();// 输入
int b[] = new int[6];// 输出
int num = 0;
for (int i = 1; i <= 5; i++) {
if (a[i] >= num)
num = a[i];// 找数组a的最大值num
}
int c[] = new int[num + 1];// 创建num+1个辅助空间c[num+1]
for (int i = 1; i <= num; i++) {// 给辅助空间c赋值为0
c[i] = 0;
}
for (int j = 1; j <= 5; j++) {
c[a[j]] = c[a[j]] + 1;// 找到a[j]在c[a[j]]中将c[a[j]]的值+1付给c[a[j]],其实就是记录a数组中的每个元素(就在c数组的对应位置)的重复个数
}
for (int i = 2; i <= num; i++) {
c[i] = c[i] + c[i - 1];// 统计前面元素出现的总个数
}
for (int j = 5; j >= 1; j--) {
b[c[a[j]]] = a[j];
c[a[j]] = c[a[j]] - 1;
}
for (int i = 1; i <= 5; i++) {
System.out.print(b[i] + " ");
}
}
}
下面是改进的算法:
package Sort;
import java.util.Scanner;
public class CountSort {
public void SortC(int[] a, int length) {
int num = 0;
for (int i = 1; i <= 5; i++) {
if (a[i] >= num)
num = a[i];// 找数组a的最大值num
}
int[] c = new int[num + 1];
for (int i = 0; i <= num; i++)
c[i] = 0;
for (int i = 0; i < length; i++) {
int as = a[i];
++c[as];
}
int index = 0;
for (int i = 0; i <= num; ++i) {
for (int j = 0; j < c[i]; ++j) {
a[index] = i;
++index;
}
}
for (int i = 1; i <= 5; i++) {
System.out.print(a[i] + " ");
}
}
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
int a[] = new int[6];
for (int i = 0; i <= 5; i++)
a[i] = reader.nextInt();// 输入
CountSort countSort = new CountSort();
countSort.SortC(a, 6);
}
}