Radix sort for 10^6 array in C [duplicate]

允我心安 提交于 2019-12-11 20:32:50

问题


i have this code and it crash in the middle of processing. System gives message "filename.exe stopped working. What is wrong here? I declare array as global to be able to have so big number of elements, but still it doesn't work.

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

#define MAX 1000000
#define SHOWPASS

void print(int *a, int n) {
 int i;
 for (i = 0; i < n; i++)
  printf("%d\t", a[i]);
}

void radix_sort(int *a, int n) {
 int i, b[MAX], m = 0, exp = 1;
 for (i = 0; i < n; i++) {
  if (a[i] > m)
   m = a[i];
 }

 while (m / exp > 0) {
  int box[10] = { 0 };
  for (i = 0; i < n; i++)
   box[a[i] / exp % 10]++;
  for (i = 1; i < 10; i++)
   box[i] += box[i - 1];
  for (i = n - 1; i >= 0; i--)
   b[--box[a[i] / exp % 10]] = a[i];
  for (i = 0; i < n; i++)
   a[i] = b[i];
  exp *= 10;

#ifdef SHOWPASS
  printf("\n\nPASS   : ");
  print(a, n);
#endif
 }
}
int arr[MAX];
int main() {
 //int arr[MAX];
 int i, num;

 printf("\nEnter total elements (num < %d) : ", MAX);
 scanf("%d", &num);

 printf("\ncreate array : ");
 for (i = 0; i < num; i++)
  arr[i]=rand()%10;

 printf("\nARRAY  : ");
 print(&arr[0], num);

 radix_sort(&arr[0], num);

 printf("\n\nSORTED  : ");
 print(&arr[0], num);

 return 0;
}

Here is another code i tried, this time i used malloc. But still it crashes before starting sort. everything is fine if number of elements is <100000.

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

#define MAX 1000000
#define SHOWPASS

void print(int *a, int n) {
 int i;
 for (i = 0; i < n; i++)
  printf("%d\t", a[i]);
}

void radix_sort(int *a, int n) {
 int i, b[MAX], m = 0, exp = 1;
 for (i = 0; i < n; i++) {
  if (a[i] > m)
   m = a[i];
 }

 while (m / exp > 0) {
  int box[10] = { 0 };
  for (i = 0; i < n; i++)
   box[a[i] / exp % 10]++;
  for (i = 1; i < 10; i++)
   box[i] += box[i - 1];
  for (i = n - 1; i >= 0; i--)
   b[--box[a[i] / exp % 10]] = a[i];
  for (i = 0; i < n; i++)
   a[i] = b[i];
  exp *= 10;

#ifdef SHOWPASS
  printf("\n\nPASS   : ");
  print(a, n);
#endif
 }
}

int i, num;
int main() {

int* arr = (int*)malloc(MAX * sizeof(int));
int i;

 printf("\ncreate array : ");
 for (i = 0; i < MAX; i++)
  arr[i]=rand()%10;

 printf("\nARRAY  : ");
 print(&arr[0], MAX);

 radix_sort(&arr[0], MAX);

 printf("\n\nSORTED  : ");
 print(&arr[0], MAX);
free(arr);
 return 0;
}

回答1:


The bug is here:

 int i, b[MAX], m = 0, exp = 1;

Allocating a huge (1 million int) array on the stack is not possible on some if not most systems.

You should malloc the temporary array and allocate only the size needed for the sort, namely n * sizeof(int).

Another problem is this: your radix_sort cannot handle negative numbers.

Less important but worth mentioning: your implementation is not stable. Not a problem for simple int arrays, but potentially incorrect for larger structures.

Furthermore, your code is inefficient: you use division and modulo 10. It would be much faster to use shifting and masking.

Here is a more efficient implementation for large arrays:

#include <limits.h>
#include <string.h>
#include <stdlib.h>

static void radix_sort(int *a, size_t size) {
    size_t counts[sizeof(*a)][256] = {{ 0 }}, *cp;
    size_t n, i, sum;
    unsigned int *tmp, *src, *dst, *aa;

    dst = tmp = malloc(size * sizeof(*a));
    src = (unsigned int *)a;
    for (i = 0; i < size; i++) {
        unsigned int v = src[i] + (unsigned int)INT_MIN;
        for (n = 0; n < sizeof(*a) * 8; n += 8)
            counts[n >> 3][(v >> n) & 255]++;
    }
    for (n = 0; n < sizeof(*a) * 8; n += 8) {
        cp = &counts[n >> 3][0];
        if (cp[0] == size) continue;
        for (i = sum = 0; i < 256; i++)
            cp[i] = (sum += cp[i]) - cp[i];
        for (i = 0; i < size; i++)
            dst[cp[((src[i] + (unsigned int)INT_MIN) >> n) & 255]++] = src[i];
        aa = src;
        src = dst;
        dst = aa;
    }
    if (src == tmp) {
        memcpy(a, src, size * sizeof(*a));
    }
    free(tmp);
}


来源:https://stackoverflow.com/questions/29362119/radix-sort-for-106-array-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!