cstructradix-sortcounting-sort

How to apply radix sort (uses counting sort) with struct containing multiple strings


I want to alphabetically sort the struct strings with radix sort, however I am struggling to apply radix sort to check each digit of the strings. I checked other posts but I couldn't find a structure similar to mine. The problem is that my code checks for each ENTRY of the struct not EACH digit of the string in that entry. (By entry I mean; table[0], table[1] etc.) So basically it sorts the string in itself of each entry. I couldn't build the logic, can someone help me please?

EDIT: the length of the strings are not the same

Here is my code:

typedef struct FUNCTIONS_STRUCT
{
    char *fncName;
    void (*fnc)(char *);
    char *description;
} FUNCTIONS_STRUCT_t;

FUNCTIONS_STRUCT_t FUNC_TABLE[] =
{

        { "ABCD", ABCD, "" },
        { "abcD", abcD, "" },
        { "EaBB", EaBB ,""}
        //it goes on ..

};

// Function to find the Largest Number
int getMax(int array[], int n) {
  int max = array[0];
  int i;
  for (i = 1; i < n; i++)
    if (array[i] > max)
      max = array[i];
  return max;
}
// Function for Count sort
void countSort(int array[], int n, int dig) {
  int output[n];
  int i, count[10] = {0};

  for (i = 0; i < n; i++)
    count[(array[i] / dig) % 10]++;

  for (i = 1; i < 10; i++)
    count[i] += count[i - 1];

  for (i = n - 1; i >= 0; i--){
    output[count[(array[i] / dig) % 10] - 1] = array[i];
    count[(array[i] / dig) % 10]--;
  }

  for (i = 0; i < n; i++)
    array[i] = output[i];

}

void radixsort(int array[], int n) {
  //Get the largest number to know the maximum number of digits
  int m = getMax(array, n);
  int dig;

  //Counting sort is performed for every digit
  for (dig = 1; m / dig > 0; dig *= 10)
    countSort(array, n, dig);
}

int main()
{
    int functionTableUnitSize = sizeof(FUNC_TABLE) / sizeof(FUNC_TABLE[0]);
    radixsort(&FUNC_TABLE, functionTableUnitSize);
    return 0;
}

Solution

  • I assume that the function names in your question have a uniform length of 4 alphanumeric characters. In C, identifiers can use 63 different alphanumeric characters from these groups:

    Different encodings have a different order (e.g. EBCDIC lower case letters are sorted before upper case letters, while the reverse is true for ASCII). For a portable C programm we can therefore define our own lexical sorting order.

    We can do this for example in a function called build_lexical_sorting_index.

    Details

    If one slightly modifies your code according to the above mentioned points, it looks like this:

    #include <stdio.h>
    
    #define UNIFORM_FUNCNAME_LENGTH 4
    
    typedef struct {
        char *fnc_name;
        void (*fnc)(char *);
        char *description;
    } FUNCTION;
    
    
    void ABCD(char *a) {};
    void abcD(char *a) {};
    void EaBB(char *a) {};
    void A012(char *a) {};
    void _ABC(char *a) {};
    
    FUNCTION func_table[] = {
            {"ABCD", ABCD, ""},
            {"abcD", abcD, ""},
            {"EaBB", EaBB, ""},
            {"A012", A012, ""},
            {"_ABC", _ABC, ""}
            //it goes on ..
    };
    int lexical_sorting_index[256] = {0};
    
    int lexical_index(int ch) {
        return lexical_sorting_index[ch];
    }
    
    void count_sort(FUNCTION *array, int n, int char_position) {
        FUNCTION output[n];
        int count[256] = {0};
    
        for (int i = 0; i < n; i++) {
            int ch = array[i].fnc_name[char_position];
            int index = lexical_index(ch);
            count[index]++;
        }
    
        for (int i = 1; i < 256; i++)
            count[i] += count[i - 1];
    
        for (int i = n - 1; i >= 0; i--) {
            int ch = array[i].fnc_name[char_position];
            int index = lexical_index(ch);
            output[count[index] - 1] = array[i];
            count[index]--;
        }
    
        for (int i = 0; i < n; i++)
            array[i] = output[i];
    }
    
    void build_lexical_sorting_index() {
        int nr = 0;
        for (int i = 'a'; i <= 'z'; i++)
            lexical_sorting_index[i] = nr++;
        for (int i = 'A'; i <= 'Z'; i++)
            lexical_sorting_index[i] = nr++;
        for (int i = '0'; i <= '9'; i++)
            lexical_sorting_index[i] = nr++;
        lexical_sorting_index['_'] = nr;
    }
    
    void radix_sort(FUNCTION *array, int n) {
        build_lexical_sorting_index();
        for(int char_position = UNIFORM_FUNCNAME_LENGTH - 1; char_position >= 0; char_position--)
            count_sort(array, n, char_position);
    }
    
    int main() {
        int table_size = sizeof(func_table) / sizeof(func_table[0]);
        radix_sort(func_table, table_size);
    
        for (int i = 0; i < table_size; i++)
            printf("%s ", func_table[i].fnc_name);
        return 0;
    }
    

    When the program is executed, the following is displayed in the debug console:

    abcD ABCD A012 EaBB _ABC