简体   繁体   中英

Improve the time complexity of my implementation of Counting Sort (C)

Consider the following code:

#define SIZE 12

void randomize(int* array, int array_size);
void print(int* array, int array_size);
void counting_sort(int* array, int array_size);
int get_max(int* array, int array_size);
void construct(int* sorted, int sorted_array_size, int* values);

int main(void)
{
    srand(time(NULL));
    int* array = (int*)malloc(sizeof(int) * SIZE);
    randomize(array, SIZE);
    print(array, SIZE);
    counting_sort(array, SIZE);
    free(array);

    return 0;
}

void randomize(int* array, int array_size) {...}

void print(int* array, int array_size) {...}

void counting_sort(int* array, int array_size) {
    int minVal, maxVal;
    int* sorted = (int*)malloc(sizeof(int) * SIZE);
    maxVal = get_max(array, array_size);

    int* values = (int*)malloc(maxVal * sizeof(int));

    memset(values, 0, maxVal * sizeof(int));

    for (int i = 0; i < array_size; i++) {
        values[array[i]]++;
    }

    construct(sorted, SIZE, values);

    free(values);
    free(sorted);
    }

int get_max(int* array, int array_size) {...}

void construct(int* sorted, int array_size, int* values) {
    for (int i = 0, j = 0; i < array_size; i++) {
        while (!values[++j]);
        sorted[i] = j;
        --values[j];
    }
    print(sorted, SIZE);
} 

main() declares an array, the size of which is controlled by the macro SIZE . Then there are a few functions to randomize, print and find the max value of that array. After that is the implementation of Counting Sort itself, which uses the construct(..) function to create the sorted array. I've tested it a few times and couldn't find any bugs. However this bit right here is what I'm concerned about.

for (int i = 0, j = 0; i < array_size; i++) {
            while (!values[++j]);...

We have 2 inner loops, and the variables in these loops are incremented. This means that the time complexity of the construct(...) function becomes quadratic, and not linear. The issue is that I can't figure out a good way to discard all of the 0 in values[] . Linear solutions are most welcome.

Added full code:

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

#define SIZE 160

void randomize(int* array, int array_size);
void print(int* array, int array_size);
void counting_sort(int* array, int array_size);
int get_max(int* array, int array_size);
void construct(int* sorted, int sorted_array_size, int* values);

int main(void)
{
    srand(time(NULL));
    int* array = (int*)malloc(sizeof(int) * SIZE);
    randomize(array, SIZE);
    print(array, SIZE);
    counting_sort(array, SIZE);
    free(array);

    return 0;
}

void randomize(int* array, int array_size) {
    for (int i = 0; i < array_size; i++) {
        array[i] = rand() % array_size;
    }
}

void print(int* array, int array_size) {
    for (int i = 0; i < array_size; i++) {
        printf("%4d ", array[i]);
    }
    putchar('\n');
}

void counting_sort(int* array, int array_size) {
    int minVal, maxVal;
    int* sorted = (int*)malloc(sizeof(int) * SIZE);
    maxVal = get_max(array, array_size);

    int* values = (int*)malloc(maxVal * sizeof(int));

    memset(values, 0, maxVal * sizeof(int));

    for (int i = 0; i < array_size; i++) {
        values[array[i]]++;
    }

    construct(sorted, SIZE, values);

    free(values);
    free(sorted);
}

int get_max(int* array, int array_size) {
    int max = INT_MIN;
    for (int i = 0; i < array_size; i++) {
        if (max < array[i]) {
            max = array[i];
        }
    }
    return max;
}

void construct(int* sorted, int array_size, int* values) {
    for (int i = 0, j = 0; i < array_size; i++) {
        while (!values[j]) {
            ++j;
        }
        sorted[i] = j;
        --values[j];
    }
    print(sorted, SIZE);
} 

Your implementation is linear. You have an inner while loop, but the value of j is never reset to 0 , it keeps growing in each iteration of the for loop. Overall i will count from 0 to size and j will count from 0 to n .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM