使用计数排序实现基数排序
计数排序是将A数组中的数字进行计数,将计数的结果存入C数组中,并将C数组中的存贮的结果,进行C[i] = C[i-1] + C[i] 将C数组进行累加存储。
// CountingSort
// A数组放进去,输出排序好的B数组
void CountingSort(int *A, int *B, int k, int n) {
int *C = (int *)malloc(sizeof(int) * (k + 1));
for (int i = 0; i <= k; i++) { // 初始化C数组
C[i] = 0;
}
for (int j = 0; j < n; j++) { // 统计A中每个元素的个数
C[A[j]]++;
}
for (int i = 1; i <= k; i++) { // 将数组C进行累加
C[i] = C[i] + C[i - 1];
}
for (int j = n - 1; j >= 0; j--) { // 将A中的元素按照C中的位置放入B中
B[C[A[j]] - 1] = A[j];
C[A[j]]--;
}
free(C);
}
基数排序是根据每个数字的位数进行排序的,将每个数的个位数进行比对之后进行排序,再以此10位,100位。若没有10位,100位的数字需要进行补0的操作。
需要解决的是如何在使用计数排序的同时,将原本数组中的数据位置同步改变。
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
# define SIZE 10
# define MAX 7
// CountingSort
// A数组放进去,输出排序好的B数组
void CountingSort(int *A, int *B, int *E, int k, int n) {
int *C = (int *)malloc(sizeof(int) * (k + 1));
for (int i = 0; i <= k; i++) { // 初始化C数组
C[i] = 0;
}
for (int j = 0; j < n; j++) { // 统计A中每个元素的个数
C[A[j]]++;
}
for (int i = 1; i <= k; i++) { // 将数组C进行累加
C[i] = C[i] + C[i - 1];
}
for (int j = n - 1; j >= 0; j--) { // 将A中的元素按照C中的位置放入B中
// 需要在调换A中元素的时候,顺便将E中的元素调换
B[C[A[j]] - 1] = A[j];
B[C[A[j]] - 1] = E[j];
C[A[j]]--;
}
free(C);
}
// 基数排序
void RadixSort(int *A, int n) {
int *B = (int *)malloc(sizeof(int) * n);
int *D = (int *)malloc(sizeof(int) * n);
int max = A[0];
for (int i = 1; i < n; i++) {
if (A[i] > max) {
max = A[i];
}
}
int d = 1;
while (max / d > 0) {
// 需要将没有的位数进行补0
for (int i = 0; i < n; i++) {
if (A[i] / d == 0) {
B[i] = 0;
}else{
B[i] = (A[i] / d) % 10;
}
}
CountingSort(B, D, A,9, n);
for (int i = 0; i < n; i++) {
A[i] = D[i];
}
d *= 10;
}
free(B);
free(D);
}
int main() {
srand((unsigned)time(NULL));
int A[SIZE] = {0};
// 位数不够的补0,所以不需要对随机生成的位数进行判断
for (int i = 0; i < SIZE; i++) {
A[i] = rand() % 1000;
printf("%d ", A[i]);
}
printf("\n");
RadixSort(A, SIZE);
for (int i = 0; i < SIZE; i++) {
printf("%d ", A[i]);
}
return 0;
}