计数排序和基数排序
计数排序
算法思想
应用范围:量大但是范围小(某大型企业数万名员工年纪排序;如何快速得到高考名次)
- 创建待排序数据
- 创建计数数组count,数组count的大小为取数的范围;数组的下标index对应的是数组范围;遍历原数组,读到原数组的数跟下标值一样时执行++操作。
- 创建结果数组,跟原数组大小相同;遍历计数数组,将计数数组下标此次填入结果数组,每个下标数量为当下标对应的值减到0时结束。
代码实现
public class 计数排序 {
public static void main(String[] args) {
int arr[] = {1, 3, 4, 5, 0, 2};
//调用计数排序方法
int[] sort = Sort(arr);
show(sort);
}
public static int[] Sort(int[] arr) {
int[] count = new int[6];
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
count[arr[i]]++;
}
for (int i = 0, j = 0; i < count.length; i++) {
while (count[i]-- > 0) {
res[j++] = i;
}
}
return res;
}
public static void show(int[] res) {
System.out.print("[");
for (int i = 0; i < res.length; i++) {
if (i < res.length-1) {
System.out.print(res[i]);
System.out.print(",");
}
else {
System.out.print(res[i]);
System.out.print("]");
}
}
}
}
----------10-15的范围------------------------------------
public class 计数排序 {
public static void main(String[] args) {
int arr[] = {11, 13, 14, 15, 10, 12};
//调用计数排序方法
int[] sort = Sort(arr);
show(sort);
}
public static int[] Sort(int[] arr) {
int[] count = new int[6];
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
int num=arr[i]-10;
count[num]++;
}
for (int i = 0, j = 0; i < count.length; i++) {
while (count[i]-- > 0) {
int num = i+10;
res[j++] = num;
}
}
return res;
}
public static void show(int[] res) {
System.out.print("[");
for (int i = 0; i < res.length; i++) {
if (i < res.length-1) {
System.out.print(res[i]);
System.out.print(",");
}
else {
System.out.print(res[i]);
System.out.print("]");
}
}
}
}
--------------解决不稳定问题--------------------------------
/*
通过一个计数数组来记录原数组中最后遍历到数字的最后位置,从后面开始遍历原数组,得到的数arr[i]在累加数组中的位置count[arr[i]]
*/
public class 计数排序 {
public static void main(String[] args) {
int arr[] = {1, 4, 3, 5, 0, 2};
//调用计数排序方法
int[] sort = Sort(arr);
System.out.print("排序后");
show(sort);
}
public static int[] Sort(int[] arr) {
int[] count = new int[6];
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
count[arr[i]]++;
}
System.out.print("计数数组");
show(count);
//累加数组,记录元素的最后一个位置
for (int i = 1; i < count.length; i++) {
count[i] = count[i] + count[i - 1];
}
System.out.print("累加数组");
show(count);
//从后遍历累加数组,找到位置直接插入,count[i]--
for (int i = arr.length-1; i >= 0; i--) {
res[--count[arr[i]]] = arr[i];
}
return res;
}
public static void show ( int[] res){
System.out.print("[");
for (int i = 0; i < res.length; i++) {
if (i < res.length - 1) {
System.out.print(res[i]);
System.out.print(",");
} else {
System.out.print(res[i]);
System.out.println("]");
}
}
}
}
总结
- 计数排序是非比较排序,属于桶排序的一种
- 适用特定问题,对数据源有一定的要求
- 时间复杂度:2N+K
- 空间复杂度:N+K
基数排序
基本思想
先找到数组的最大值,得到最大值的位数,先排个位,思想跟计数排序类似。
public static int[] Sort(int[] arr, int length) {
int[] count = new int[10];
int[] res = new int[arr.length];
for (int i = 0; i < length; i++) {
int division = (int) Math.pow(10, i);
System.out.println(division);
//得到每位数的个位,放在桶计数数组中
for(int j=0;j<arr.length;j++){
int num = arr[j] / division % 10;
count[num]++;
}
System.out.print("计数数组");
show(count);
//累加数组,记录元素的最后一个位置
for (int m = 1; m < count.length; m++) {
count[m] = count[m] + count[m - 1];
}
System.out.print("累加数组");
show(count);
//计数排序
for(int n=arr.length-1;n>=0;n--){
int num = arr[n] / division % 10;
res[--count[num]]=arr[n];
}
Arrays.fill(count,0);
show(res);
}
return res;
}

浙公网安备 33010602011771号