使用C实现基数排序

Posted

技术标签:

【中文标题】使用C实现基数排序【英文标题】:Using C to implement radix sort 【发布时间】:2016-11-29 14:56:10 【问题描述】:

我在下面的问题中卡住了几天。我用C实现了基数排序,除了一行代码,一切都很好。你能帮我解决这个问题吗?

我的问题出在 radix_sort 函数的第一行。当我使用int semi_sort[12] 时,我可以正确运行程序。但是,我想使用传递给函数的大小变量,但是当我使用 int semi_sort[size] 而不是 int semi_sort[12] 时,我的程序会崩溃。谁能告诉我这是为什么?顺便说一句,我提到了this link,在这个作者的代码中,他做了int semiSorted[size]。为什么这行代码这次能行?

提前谢谢你!!

#include <stdio.h>
#include <stdlib.h>

#define bucket_size 10

int find_the_largest(int arr[],int size);
void display(int arr[],int size);
void radix_sort(int arr[],int size);

int main()

    printf("------------------------------------------------------\n");
    printf("        Hey! This is a radix sort algorithm!\n");
    printf("------------------------------------------------------\n\n");
    int array[] = 10, 2, 303, 4021, 293, 1, 0, 429, 480, 92, 2999, 14;
    int size = sizeof(array)/sizeof(int);
    int largest_num = find_the_largest(array,size);
    printf("The unsorted array:");
    display(array,size);
    printf("The radix sort algorithm:\n\n");
    radix_sort(array,size);
    display(array,size);
    return 0;


int find_the_largest(int arr[],int size)
    int i,max_num=0;
    for(i=0;i<size;i++)
        if(arr[i]>max_num)
            max_num = arr[i];
    
    return max_num;


void display(int arr[],int size)
    int i;
    for(i=0;i<size;i++)
        printf(" %d",arr[i]);
    if(i==size-1)
        printf("\n\n");
    


void radix_sort(int arr[],int size)

    int semi_sort[12];
    int max_num = find_the_largest(arr,size);
    int i,significant_num = 1;

    while(max_num/significant_num>0)
        int bucket[bucket_size] = 0;

        for(i=0;i<size;i++)
            bucket[(arr[i]/significant_num)%10]++;
        

        for(i=1;i<size;i++)
            bucket[i] += bucket[i-1];
        

        for(i=size-1;i>=0;i--)

            semi_sort[--bucket[(arr[i]/significant_num)%10]] = arr[i];
        


        for(i=0;i<size;i++)
            arr[i] = semi_sort[i];

        significant_num *= 10;
    

【问题讨论】:

如果您使用 C 编程,为什么要添加 C++ 标签?不要添加不相关的标签。 请注意,您在main() 中分配给largest_num,但从不使用它。您应该删除它——让基数排序代码调用该函数。 【参考方案1】:

你的代码有问题:

for(i=1;i<size;i++)
    bucket[i] += bucket[i-1];

因为size 可以大于bucket_size

你可能有以下问题:

for(i=size-1;i>=0;i--)
    semi_sort[--bucket[(arr[i]/significant_num)%10]] = arr[i];

因为--bucket[(arr[i]/significant_num)%10] 可以大于 11 或小于 0。

find_the_largest 不能正确处理负数。

您可以为缓冲区动态分配内存,如下所示:

semi_sort = malloc(size * (sizeof *semi_sort));

别忘了在结束时释放内存 (free(semi_sort))。

【讨论】:

感谢您的回复!对于您提到的前两个 for 循环,我认为这对我的实现来说没问题,因为我将其视为仅处理正数的排序。除了使用 malloc,我可以在声明数组时只在数组中使用变量吗?非常感谢朋友! 如果我理解正确,你必须声明指向数组的指针,它的内存将被分配。 int *semi_sort; ... semi_sort = malloc(size * (sizeof *semi_sort)); ... --bucket[(arr[i]/significant_num)%10] can be greater then 11 or less then 0。该值不应小于 0,因为 bucket[(arr[i]/significant_num)%10] 的增量是 (arr[i]/significant_num)%10 发生的次数。预减后的最大值将为 size-1。

以上是关于使用C实现基数排序的主要内容,如果未能解决你的问题,请参考以下文章

LinkedList 中的 C# 基数排序实现

计数排序和基数排序的实现

使用 CUDA 在 C 中并行化基数排序的问题

如何使用基数排序对变长字符串数组进行排序?

了解 C 中的基数排序

基数排序算法说明