蓝桥杯每日一题---基数排序

题目

分析

在实际的比赛过程中很少会自己手写排序,顶多是定义一下排序规则。之所以要练习一下基数排序,是因为在后续学习过程中学到后缀数组时需要自己手写基数排序,那么这里使用的方法也和后缀数组一致,理解这里也便于后缀数组的学习。

桶排序全流程回顾

原数组:12 34 26 123 14 7

  1. 根据第一关键字即个位数放桶
    2号桶:12
    3号桶:123
    4号桶:34 14
    6号桶:26
    7号桶:7
  2. 根据关键字实现一轮排序
    12 123 34 14 26 7
  3. 根据第二关键字即十位数放桶
    0号桶:7
    1号桶:12 14
    2号桶:123 26
    3号桶:34
  4. 根据关键字实现一轮排序
    7 12 14 123 26 34
  5. 根据第三关键字即百位数放桶
    0号桶:7 12 14 26 34
    1号桶:123
  6. 根据关键字实现一轮排序
    7 12 14 26 34 123
    经过三轮排序后,原数组有序。

基数排序过程详细分析

标记每个数字属于哪个桶

直接通过数字对应的关键字表示就可以了,可以写一个get(x,k)函数,表示取出数字x的第k个关键字,代码如下

java 复制代码
private static int get(int a,int k) {
	int id = 1;
	while(a>0) {
		if(id == k) return a%10;
		a/=10;
		id++;
	}
	return 0;
}

统计桶内存放的数字个数

count[get(a[j],i)]++;

2号桶(count=1):12

3号桶(count=1):123

4号桶(count=2):34 14

6号桶(count=1):26

7号桶(count=1):7

计算count的前缀和数组

count[j] += count[j-1];

2号桶(累积count=1):12

3号桶(累积count=2):123

4号桶(累积count=4):34 14

6号桶(累积count=5):26

7号桶(累积count=6):7

根据前缀和统计本轮排序后每个数字的位序

bu[count[get(a[j], i)]--] = a[j];

2号桶(累积count[2]=1):12

3号桶(累积count[3]=2):123

4号桶(累积count[4]=4):34 14

6号桶(累积count[6]=5):26

7号桶(累积count[7]=6):7

数字7的位序位累积count=6

数字26的位序位累积count=5

数字14的位序位累积count=4 count- -=3

数字34的位序位累积count=3

数字123的位序位累积count=2

数字12的位序位累积count=1

一轮排序后的结果为:

12 123 34 14 26 7

完整代码

javascript 复制代码
import java.util.Arrays;
import java.util.Scanner;
public class 基数排序{
public static void main(String[] args) {
	Scanner scanner = new Scanner(System.in);
	int n = scanner.nextInt();
	int a[] = new int[n+1];
	int maxV = 0,max = 0;
	for (int i = 1; i <= n; i++) {
		a[i] = scanner.nextInt();
		maxV = Math.max(maxV, a[i]);
	}		
	int count[] = new int[10];
	int bu[] = new int[n+1];
	while(maxV > 0) {
		maxV /= 10;
		max++;
	}
	for(int i = 1;i <= max;i++) {
		Arrays.fill(count, 0);
		for (int j = 1; j <= n; j++) count[get(a[j],i)]++;
		for (int j = 1; j <= 9; j++) count[j] += count[j-1];
		for (int j = n; j > 0; j--) {
			int k = get(a[j], i);
			bu[count[k]--] = a[j];
		}
		for (int j = 1; j <= n; j++) a[j]=bu[j];
	}
	for (int i = 1; i <= n; i++)
		System.out.print(a[i] + " ");
}

private static int get(int a,int k) {
	int id = 1;
	while(a>0) {
		if(id == k) return a%10;
		a/=10;
		id++;
	}
	return 0;
}
}
相关推荐
测试涛叔16 分钟前
金三银四软件测试面试题(800道)
软件测试·面试·职场和发展
Angelina_Jolie1 小时前
一文搞懂 SCI、SSCI、CSSCI、C 刊、核心期刊:定义、作用、层级对比及投稿选择
考研·职场和发展·创业创新
User_芊芊君子3 小时前
【LeetCode经典题解】搞定二叉树最近公共祖先:递归法+栈存路径法,附代码实现
算法·leetcode·职场和发展
熬夜造bug3 小时前
LeetCode Hot100 刷题路线(Python版)
算法·leetcode·职场和发展
测试者家园8 小时前
测试用例智能生成:是效率革命,还是“垃圾进,垃圾出”的新挑战?
人工智能·职场和发展·测试用例·测试策略·质量效能·智能化测试·用例设计
win x10 小时前
JavaSE(基础)高频面试点及 知识点
java·面试·职场和发展
橘颂TA13 小时前
【剑斩OFFER】算法的暴力美学——力扣 207 题:课程表
数据结构·c++·算法·leetcode·职场和发展
谁刺我心13 小时前
【蓝桥杯刷题环境】VScode插件算法刷题Competitive Companion
职场和发展·蓝桥杯
有一个好名字13 小时前
力扣-迷宫中离入口最近的出口
算法·leetcode·职场和发展
努力学算法的蒟蒻13 小时前
day72(1.31)——leetcode面试经典150
面试·职场和发展