Cod sursa(job #522782)

Utilizator dudu77tTudor Morar dudu77t Data 16 ianuarie 2011 03:58:41
Problema Sortare prin comparare Scor 60
Compilator c Status done
Runda Arhiva educationala Marime 2.51 kb
#include <stdio.h>
#include <stdlib.h>

const int BIT_CHUNK = 8;
const int MAX_BITS = 32;
int NO_OF_VALUES;
int BIT_MASK;
int MAX_LEVEL;

int *sort(int*, int*, int, int);
void MSBsort(int*, int, int);

int main() {
    NO_OF_VALUES = 1 << BIT_CHUNK;
    BIT_MASK = NO_OF_VALUES - 1;
    MAX_LEVEL = MAX_BITS / BIT_CHUNK - 1;

    freopen("algsort.in", "r", stdin);
    freopen("algsort.out", "w", stdout);
    int i, n;
    scanf("%d", &n);

    int *array = (int*)malloc(n * sizeof(*array));
    int  *temp = (int*)malloc(n * sizeof( *temp));

    for (i = 0; i < n; ++i)
        scanf("%d", &array[i]);

//    int *sorted = sort(array, temp, n, 0);
    int *sorted = array;
    MSBsort(array, n, MAX_LEVEL);

    for (i = 0; i < n; ++i)
        printf("%d ", sorted[i]);

    return 0;
}

int *sort(int *array, int *temp, int size, int level) {
    int *occurences = (int*)calloc(NO_OF_VALUES, sizeof(*occurences));
    int      *index = (int*)calloc(NO_OF_VALUES, sizeof(     *index));
    int i;

    for (i = 0; i < size; ++i)
        ++occurences[(array[i] >> (level * BIT_CHUNK)) & BIT_MASK];

    for (i = 1; i < NO_OF_VALUES; ++i)
        index[i] = index[i - 1] + occurences[i - 1];

    for (i = 0; i < size; ++i) {
        int d = array[i];
        int k = (d >> (level * BIT_CHUNK)) & BIT_MASK;
        temp[index[k]++] = d;
    }

    free(occurences);
    free(index);

    if (level < MAX_LEVEL)
        return sort(temp, array, size, level + 1);
    return temp;
}

void swap(int *a, int *b) {
    int t = *a;
    *a = *b;
    *b = t;
}

void MSBsort(int *array, int size, int level) {
    int *occurences = (int*)calloc(NO_OF_VALUES, sizeof(*occurences));
    int      *index = (int*)calloc(NO_OF_VALUES, sizeof(     *index));
    int      *start = (int*)calloc(NO_OF_VALUES, sizeof(     *start));
    int i;

    for (i = 0; i < size; ++i)
        ++occurences[(array[i] >> (level * BIT_CHUNK)) & BIT_MASK];

    for (i = 1; i < NO_OF_VALUES; ++i)
        index[i] = start[i] = index[i - 1] + occurences[i - 1];

    for (i = 0; i < size; ++i) {
        int d = array[i];
        int k = (d >> (level * BIT_CHUNK) & BIT_MASK);
        if (i >= start[k] && i < start[k] + occurences[k])
            ++index[k];
        else {
            swap(&array[i], &array[index[k]]);
            ++index[k];
            --i;
        }
    }

    if (level > 0)
        for (i = 0; i < NO_OF_VALUES; ++i)
            if (occurences[i])
                MSBsort(array + start[i], occurences[i], level - 1);

    free(occurences);
    free(index);
    free(start);
}