【C语言】使用计数排序实现基数排序

使用计数排序实现基数排序

计数排序是将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;
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下为使用C语言实现基数计数排序的代码: ```c #include <stdio.h> #include <stdlib.h> // 求出数组中最大的数 int getMax(int arr[], int n) { int max = arr[0]; for (int i = 1; i < n; i++) { if (arr[i] > max) { max = arr[i]; } } return max; } // 基数计数排序 void radixCountingSort(int arr[], int n) { int max = getMax(arr, n); // 求出数组中最大的数 int exp = 1; // 初始位数为1 int *count = (int*)malloc(sizeof(int) * 10); // 计数数组 int *output = (int*)malloc(sizeof(int) * n); // 输出数组 while (max / exp > 0) { // 初始化计数数组 for (int i = 0; i < 10; i++) { count[i] = 0; } // 统计每个元素出现的次数 for (int i = 0; i < n; i++) { count[(arr[i] / exp) % 10]++; } // 计算每个元素在输出数组中的位置 for (int i = 1; i < 10; i++) { count[i] += count[i - 1]; } // 将元素按照计数数组中的位置,放入输出数组中 for (int i = n - 1; i >= 0; i--) { output[count[(arr[i] / exp) % 10] - 1] = arr[i]; count[(arr[i] / exp) % 10]--; } // 将输出数组中的元素复制到原数组中 for (int i = 0; i < n; i++) { arr[i] = output[i]; } // 位数增加 exp *= 10; } free(count); free(output); } // 输出数组中的元素 void printArray(int arr[], int n) { for (int i = 0; i < n; i++) { printf("%d ", arr[i]); } printf("\n"); } int main() { int arr[] = { 170, 45, 75, 90, 802, 24, 2, 66 }; int n = sizeof(arr) / sizeof(arr[0]); printf("原数组:\n"); printArray(arr, n); radixCountingSort(arr, n); printf("排序后的数组:\n"); printArray(arr, n); return 0; } ``` 使用方法: 1. 将上述代码保存为一个名为`radix_counting_sort.c`的文件; 2. 打开终端或命令行窗口,进入代码所在的目录; 3. 输入以下命令编译代码:`gcc radix_counting_sort.c -o radix_counting_sort`; 4. 输入以下命令运行程序:`./radix_counting_sort`。 程序运行结果如下: ``` 原数组: 170 45 75 90 802 24 2 66 排序后的数组: 2 24 45 66 75 90 170 802 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值