C 基数排序循环错误

C 基数排序循环错误,c,sorting,radix-sort,C,Sorting,Radix Sort,我试图在C中实现整数的基数排序,但遇到了一个似乎无法修复的循环错误。下面是代码和输出。我不知道确切的部分是错误的,所以请原谅后的长度 有人能指出我的错误吗 #include <stdio.h> #define BINS 16 #define GROUP 4 int main(int argc, const char *argv[]) { int mask = 0xf; int i, j; int list[] = {0x65c6, 0xbeb, 0x96ba

我试图在C中实现整数的基数排序,但遇到了一个似乎无法修复的循环错误。下面是代码和输出。我不知道确切的部分是错误的,所以请原谅后的长度

有人能指出我的错误吗

#include <stdio.h>
#define BINS 16
#define GROUP 4

int main(int argc, const char *argv[])
{
    int mask = 0xf;
    int i, j;
    int list[] = {0x65c6, 0xbeb, 0x96ba, 0x9a7d};
    int buffer[GROUP];
    int *temp, *src_ptr, *dest_ptr;
    int cnt[BINS];
    int map[BINS];
    map[0] = 0;

    //init pointers to the list of unsorted numbers and temp buffer
    src_ptr = list;
    dest_ptr = buffer;

    //print unsorted list
    putchar('\n');
    printf("unsorted list: \n");
    for(i = 0; i < GROUP; i++) 
        printf("int: %d hex: 0x%x ", src_ptr[i], src_ptr[i]);
    putchar('\n');

    j = 0;
    while(j < GROUP)
    {
        //initalize the count
        for(i = 0; i < BINS; i++)
            cnt[i] = 0;
        
        //count significant digits. shifting i * group # of times
        for(i = 0; i < GROUP; i++)
            cnt[(src_ptr[i] >> i*GROUP) & mask]++;

        //initalize the map
        map[0] = 0;
        for(i = 0; i < BINS; i++)
            map[i] = 0;

        //compute the map
        for(i = 1; i < BINS; i++)
        {
            map[i] = (map[i - 1] + cnt[i - 1]);
        }

        //shift the elements in buffer[] and list[] via their pointers. 
        //shifting i * group # of times
        for(i = 0; i < GROUP; i++)
        {
            dest_ptr[map[(src_ptr[i] >> i*GROUP) & mask]++] = src_ptr[i];
        }

        //perform a swap of list[] and buffer[] via their pointers
        temp = src_ptr;
        src_ptr = dest_ptr;
        dest_ptr = src_ptr;
    
        j++;
    }

    //print list for reference
    putchar('\n');
    printf("sorted list: \n");
    for(i = 0; i < GROUP; i++) 
        printf("int: %d hex: 0x%x ", src_ptr[i], src_ptr[i]);
    putchar('\n');
    
    //print buffer for reference
    putchar('\n');
    printf("sorted buffer: \n");
    for(i = 0; i < GROUP; i++) 
        printf("int: %d hex: 0x%x ", dest_ptr[i], dest_ptr[i]);
    putchar('\n');

    return 0;
}    
#包括
#定义存储箱16
#定义第4组
int main(int argc,const char*argv[]
{
int mask=0xf;
int i,j;
int list[]={0x65c6,0xbeb,0x96ba,0x9a7d};
int缓冲区[组];
int*temp、*src\U ptr、*dest\U ptr;
国际碳纳米管[箱];
int-map[bin];
map[0]=0;
//init指向未排序的数字和临时缓冲区列表的指针
src_ptr=列表;
dest_ptr=缓冲区;
//打印未排序的列表
putchar('\n');
printf(“未排序的列表:\n”);
对于(i=0;i>i*组)和mask]++;
//初始化地图
map[0]=0;
对于(i=0;i>i*组)和mask]+]=src_ptr[i];
}
//通过其指针执行列表[]和缓冲区[]的交换
温度=src_ptr;
src_ptr=dest_ptr;
dest_ptr=src_ptr;
j++;
}
//打印列表以供参考
putchar('\n');
printf(“排序列表:\n”);
对于(i=0;i
输出:

未排序的原始列表: 内部代码:26054十六进制代码:0x65c6内部代码:3051十六进制代码:0xbeb内部代码:38586十六进制代码:0x96ba内部代码:39549十六进制代码:0x9a7d

已排序列表: 内部:3051十六进制:0xbeb内部:3051十六进制:0xbeb内部:3051十六进制:0xbeb内部:3051十六进制:0xbeb

已排序的缓冲区: 内部:3051十六进制:0xbeb内部:3051十六进制:0xbeb内部:3051十六进制:0xbeb内部:3051十六进制:0xbeb


代码中有两个问题:


  • 您的交换代码:
    temp=src\u ptr;src_ptr=dest_ptr;dest_ptr=src_ptr应该引用
    temp
    两次(我的编译器告诉我你做错了,因为它说“
    错误:变量'temp'设置但未使用[-Werror=unused but set variable]
    ”)。您需要让编译器生成类似的警告,然后注意它们。交换代码应为:
    temp=src\u ptr;src_ptr=dest_ptr;dest_ptr=温度当然。这是一个必要的改变;这还不够

    我希望我的代码能够在以下条件下干净地编译:

    gcc -g -O3 -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Wold-style-declaration -Werror  radixsort.c -o radixsort
    
  • 换档时未正确使用
    j
    。你有:

    cnt[(src_ptr[i] >> i*GROUP) & mask]++;
    dest_ptr[map[(src_ptr[i] >> i*GROUP) & mask]++] = src_ptr[i];
    
    你需要:

    cnt[(src_ptr[i] >> j*GROUP) & mask]++;
    dest_ptr[map[(src_ptr[i] >> j*GROUP) & mask]++] = src_ptr[i];
    
  • 此代码似乎排序正确:

    #include <stdio.h>
    
    enum { BINS  = 16  };
    enum { GROUP = 4   };
    enum { MASK  = 0xF };
    
    static void dump_array(char const *tag, size_t n, int a[n])
    {
        printf("%s:\n", tag);
        for (size_t i = 0; i < n; i++)
            printf("int: %5d hex: 0x%.4X\n", a[i], a[i]);
    }
    
    int main(void)
    {
        int i, j;
        int list[] = {0x65C6, 0x0BEB, 0x96BA, 0x9A7D};
        int buffer[GROUP];
        int *temp, *src_ptr, *dest_ptr;
        int cnt[BINS];
        int map[BINS];
        map[0] = 0;
    
        // init pointers to the list of unsorted numbers and temp buffer
        src_ptr = list;
        dest_ptr = buffer;
    
        // print unsorted list
        dump_array("unsorted list", GROUP, src_ptr);
    
        j = 0;
        while (j < GROUP)
        {
            // initalize the count
            for (i = 0; i < BINS; i++)
                cnt[i] = 0;
    
            // count significant digits. shifting i * group # of times
            for (i = 0; i < GROUP; i++)
                cnt[(src_ptr[i] >> j*GROUP) & MASK]++;
    
            // initalize the map
            map[0] = 0;
            for (i = 0; i < BINS; i++)
                map[i] = 0;
    
            // compute the map
            for (i = 1; i < BINS; i++)
            {
                map[i] = (map[i - 1] + cnt[i - 1]);
            }
    
            // shift the elements in buffer[] and list[] via their pointers.
            // shifting i * group # of times
            for (i = 0; i < GROUP; i++)
            {
                dest_ptr[map[(src_ptr[i] >> j*GROUP) & MASK]++] = src_ptr[i];
            }
    
            // perform a swap of list[] and buffer[] via their pointers
            temp = src_ptr;
            src_ptr = dest_ptr;
            dest_ptr = temp;
            j++;
        }
    
        // print list for reference
        dump_array("sorted list", GROUP, src_ptr);
    
        // print buffer for reference
        dump_array("sorted buffer", GROUP, dest_ptr);
    
        return 0;
    }
    
    广义码 上述代码将
    用于两个不同的目的。一个是要排序(和打印)的列表长度。一个是用于基数排序的数字组数。下面的代码用于将列表大小与基数组分开。它还清理原始代码中未修复的一些注释等

    #include <stdio.h>
    
    enum { BINS  = 16  };
    enum { GROUP = 4   };
    enum { MASK  = 0xF };
    
    static void dump_array(char const *tag, size_t n, int a[n])
    {
        printf("%s:\n", tag);
        for (size_t i = 0; i < n; i++)
            printf("int: %5d hex: 0x%.4X\n", a[i], a[i]);
    }
    
    int main(void)
    {
        int list[] = {0x65C6, 0x0BEB, 0x96BA, 0x9A7D, 0x2917, 0x8A2C, 0xDEAD, 0xBEEF, 0xFACE };
        enum { LIST_SIZE = sizeof(list) / sizeof(list[0]) };
        int buffer[LIST_SIZE];
        int cnt[BINS];
        int map[BINS];
    
        // init pointers to the list of unsorted numbers and temp buffer
        int *src_ptr = list;
        int *dst_ptr = buffer;
    
        // print unsorted list
        dump_array("unsorted list", LIST_SIZE, src_ptr);
    
        for (int j = 0; j < GROUP; j++)
        {
            // initalize the count
            for (int i = 0; i < BINS; i++)
                cnt[i] = 0;
    
            // count significant digits. shifting j * group # of times
            for (int i = 0; i < LIST_SIZE; i++)
                cnt[(src_ptr[i] >> j*GROUP) & MASK]++;
    
            // initalize the map
            for (int i = 0; i < BINS; i++)
                map[i] = 0;
    
            // compute the map
            for (int i = 1; i < BINS; i++)
                map[i] = (map[i - 1] + cnt[i - 1]);
    
            // shift the elements in buffer[] and list[] via their pointers.
            // shifting j * group # of times
            for (int i = 0; i < LIST_SIZE; i++)
                dst_ptr[map[(src_ptr[i] >> j*GROUP) & MASK]++] = src_ptr[i];
    
            // perform a swap of list[] and buffer[] via their pointers
            int *tmp_ptr = src_ptr;
            src_ptr = dst_ptr;
            dst_ptr = tmp_ptr;
        }
    
        // print list for reference
        dump_array("sorted list", LIST_SIZE, src_ptr);
    
        // print buffer for reference
        dump_array("sorted buffer", LIST_SIZE, dst_ptr);
    
        return 0;
    }
    

    您的交换代码:
    temp=src\u ptr;src_ptr=dest_ptr;dest_ptr=src_ptr应该引用
    temp
    两次(我的编译器告诉我你做错了,因为它说“错误:变量'temp'设置但未使用[-Werror=unused but set variable]”)。您需要让编译器生成类似的警告,然后注意它们。交换代码应为:
    temp=src\u ptr;src_ptr=dest_ptr;dest_ptr=温度当然。这是一个必要的改变(假设那里需要互换);这不是一个足够的改变。呸!落后你1分钟!FGITW再次攻击:D(这是西方最快的枪)。谢谢。我在我的机器上尝试了这个版本,但它似乎排序不正确。但是如果我将while循环上的终止条件更改为8,即
    while(j<8)
    。它工作正常。有什么建议吗?我没有使用
    dump\u数组
    函数。不知道。为什么不使用与
    dump\u array()函数等效的函数呢?您喜欢多次编写相同的代码吗?这些函数在调试代码时非常有用。如果尝试对列表中的4个以上项目进行排序,或者尝试对0x0000..0xFFFF范围之外的值进行排序,则原始代码将无法很好地适应。查看我的修订。我并不是说我反对使用
    dump\u array
    函数,我只是根据您的代码做了一些快速更改。我确实同意
    dump\u数组
    更好。但至于我的循环问题,即
    while(j<8)
    。我意识到原来的代码应该是
    (而j
    
    #include <stdio.h>
    
    enum { BINS  = 16  };
    enum { GROUP = 4   };
    enum { MASK  = 0xF };
    
    static void dump_array(char const *tag, size_t n, int a[n])
    {
        printf("%s:\n", tag);
        for (size_t i = 0; i < n; i++)
            printf("int: %5d hex: 0x%.4X\n", a[i], a[i]);
    }
    
    int main(void)
    {
        int list[] = {0x65C6, 0x0BEB, 0x96BA, 0x9A7D, 0x2917, 0x8A2C, 0xDEAD, 0xBEEF, 0xFACE };
        enum { LIST_SIZE = sizeof(list) / sizeof(list[0]) };
        int buffer[LIST_SIZE];
        int cnt[BINS];
        int map[BINS];
    
        // init pointers to the list of unsorted numbers and temp buffer
        int *src_ptr = list;
        int *dst_ptr = buffer;
    
        // print unsorted list
        dump_array("unsorted list", LIST_SIZE, src_ptr);
    
        for (int j = 0; j < GROUP; j++)
        {
            // initalize the count
            for (int i = 0; i < BINS; i++)
                cnt[i] = 0;
    
            // count significant digits. shifting j * group # of times
            for (int i = 0; i < LIST_SIZE; i++)
                cnt[(src_ptr[i] >> j*GROUP) & MASK]++;
    
            // initalize the map
            for (int i = 0; i < BINS; i++)
                map[i] = 0;
    
            // compute the map
            for (int i = 1; i < BINS; i++)
                map[i] = (map[i - 1] + cnt[i - 1]);
    
            // shift the elements in buffer[] and list[] via their pointers.
            // shifting j * group # of times
            for (int i = 0; i < LIST_SIZE; i++)
                dst_ptr[map[(src_ptr[i] >> j*GROUP) & MASK]++] = src_ptr[i];
    
            // perform a swap of list[] and buffer[] via their pointers
            int *tmp_ptr = src_ptr;
            src_ptr = dst_ptr;
            dst_ptr = tmp_ptr;
        }
    
        // print list for reference
        dump_array("sorted list", LIST_SIZE, src_ptr);
    
        // print buffer for reference
        dump_array("sorted buffer", LIST_SIZE, dst_ptr);
    
        return 0;
    }
    
    unsorted list:
    int: 26054 hex: 0x65C6
    int:  3051 hex: 0x0BEB
    int: 38586 hex: 0x96BA
    int: 39549 hex: 0x9A7D
    int: 10519 hex: 0x2917
    int: 35372 hex: 0x8A2C
    int: 57005 hex: 0xDEAD
    int: 48879 hex: 0xBEEF
    int: 64206 hex: 0xFACE
    sorted list:
    int:  3051 hex: 0x0BEB
    int: 10519 hex: 0x2917
    int: 26054 hex: 0x65C6
    int: 35372 hex: 0x8A2C
    int: 38586 hex: 0x96BA
    int: 39549 hex: 0x9A7D
    int: 48879 hex: 0xBEEF
    int: 57005 hex: 0xDEAD
    int: 64206 hex: 0xFACE
    sorted buffer:
    int: 26054 hex: 0x65C6
    int: 38586 hex: 0x96BA
    int: 10519 hex: 0x2917
    int: 35372 hex: 0x8A2C
    int: 39549 hex: 0x9A7D
    int: 64206 hex: 0xFACE
    int:  3051 hex: 0x0BEB
    int: 57005 hex: 0xDEAD
    int: 48879 hex: 0xBEEF