计数排序
- 一句话:用辅助数组对数组中出现的数字计数,元素转下标,下标转元素
- 步骤:
1、找出原数组中元素值最大的,记为max。
2、创建一个新数组helper其长度是max加1,其元素默认值都为0。
3、遍历原数组中的元素,以原数组中的元素作为helper数组的索引,以原数组中的元素出现次数作为helper数组的元素值。
4、创建结果数组result,起始索引index。
5、 遍历helper数组,找出其中元素值大于0的元素,将其对应的索引作为元素值填充到result数组中去,每处理一次,count中的该元素值减1,直到该元素值不大于0,依次处理count中剩下的元素。
6、返回结果数组result。
import java.util.Scanner;
public class LianXi {
public static void countSort(int []A){
//找出数组A的最大值
int max = Integer.MIN_VALUE;
for(int num : A){
max = Math.max(max, num);
}
//初始化计数数组helper
int []helper = new int[max+1];
//对计数数组各元素赋值
for(int num : A){
helper[num]++;
}
//创建结果数组
int []result = new int[A.length];
//创建结果数组的起始索引
int index = 0;
//遍历计数数组,将计数数组的索引填充到结果数组中
for(int i = 0; i<helper.length; i++){
while(helper[i]>0){
result[index++] = i;
helper[i]--;
}
}
for(int i = 0; i<result.length; i++){
System.out.print(result[i] + " ");
}
}
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int N = in.nextInt();
int []A = new int[N];
for(int i = 0; i<N; i++){
A[i] = in.nextInt();
}
System.out.println("初始数组为:");
for(int i = 0; i<N; i++){
System.out.print(A[i] + " ");
}
System.out.println("\n");
System.out.println("计数排序后数组为:");
countSort(A);
}
}
基数排序
基数排序过程无须比较关键字,而是“分配”和“收集”过程来实现排序,它的时间复杂度可达到线性阶 O(n)。对于十进制数来说,每一位的数在{0,9}之中,d位的数,则有d列。基数排序首先按低位有效数字进行排。然后逐次向上一位进行排序,直到最高位排序结束。
约定:待排序数组中没有0,没有负数(有负数,做一次转换全部变为正数即可)
import java.util.ArrayList;
import java.util.Scanner;
public class LianXi {
//10个桶,每个桶装的数个数不定,适合用数组加ArrayList
private static ArrayList[] bucket = new ArrayList[10];
//初始化桶
static {
for(int i = 0; i < bucket.length; i++){
bucket[i] = new ArrayList();
}
}
//将数组arr,按d这个位来分配和收集
private static void sort(int[] arr, int d){
//全部入桶
for(int i = 0; i < arr.length; i++){
putInBucket(arr[i],getDigitOn(arr[i], d));
}
//每个桶中的元素依次压入原数组
int k = 0;
for(int j = 0; j < bucket.length; j++){
//每个桶
for(Object m : bucket[j]){
arr[k++] = (Integer) m;
}
}
//记得清空
clearAll();
}
public static void putInBucket(int data, int digitOn){
switch(digitOn){
case 0:
bucket[0].add(data);
break;
case 1:
bucket[1].add(data);
break;
case 2:
bucket[2].add(data);
break;
case 3:
bucket[3].add(data);
break;
case 4:
bucket[4].add(data);
break;
case 5:
bucket[5].add(data);
break;
case 6:
bucket[6].add(data);
break;
case 7:
bucket[7].add(data);
case 8:
bucket[8].add(data);
break;
case 9:
bucket[9].add(data);
break;
}
}
//获取第d为上的数
private static int getDigitOn(int i, int d) {
if(d <= 1)
return i%10;
int num = i / ((d-1) * 10) % 10;
return num;
}
private static void clearAll() {
for(ArrayList b : bucket){
b.clear();
}
}
public static void sort(int[] arr){
//入桶依据的位初始化为1
int d = 1;
//获取最大值
int max = Integer.MIN_VALUE;
for(int num : arr){
max = Math.max(max, num);
}
//最大数据的位数
int dNum = 1;
while(max / 10 != 0){
dNum++;
max /= 10;
}
while(d<=dNum){
//依据第二个参数入桶和出桶
sort(arr, d++);
}
}
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int N = in.nextInt();
int []arr = new int[N];
for(int i = 0; i<N; i++){
arr[i] = in.nextInt();
}
System.out.println("初始数组为:");
for(int i = 0; i<N; i++){
System.out.print(arr[i] + " ");
}
System.out.println("\n");
sort(arr);
System.out.println("基数排序后数组为:");
for(int i = 0; i<N; i++){
System.out.print(arr[i] + " ");
}
}
}