Сортировка по основанию с использованием очереди

Я хотел создать реализацию сортировки по основанию с использованием очередей.

Я не мог понять, в какой части моего кода есть проблемы или какие ресурсы я должен прочитать. Мой код может быть совершенно неправильным, но это моя реализация без какой-либо помощи (я еще не прошел курс по структурам данных и алгоритмам).

Я создал функцию, но она не сработала. Во время исследования я видел несколько примеров кода, но они показались мне более сложными.

Во-первых я хотел найти наименьшую значащую цифру всех целых чисел Затем отсортировать их в элементе очереди, индекс которого совпадает, затем после сортировки скопировать все очереди в конец 11-го элемента очереди. Повторите эту сортировку в 11-м элементе очереди, пока не достигнете старшей значащей цифры.

Я смог найти младшую значащую цифру. И отсортировать по этой цифре. Но я не мог анализировать другие цифры. Например; Я мог бы отсортировать 1, 2, 4, 5, 3, но когда приходит время отсортировать 2 или более цифр, это не удается...

Надеюсь, я был понятен и кратко объяснил свою проблему.

// My function declaration
// Pre: arrInts holds the linked list of integers which are going to be sort.
// Post: queue will return result and its 11th element should hold sorted integers in
//       that queue
queue_node_t * radixSort(const queue_node_t *arrInts, queue_t *queue[], int size){
    queue_node_t *curNodep = arrInts; // Node to be checked
    int i, curNum = curNodep->element.key;
    if(curNodep == NULL){
        // If there is no other node left then assign them into 11th queue.
        for(i=0;i<=9;i++){
            if(queue[i]->rearp!=NULL){
                if(queue[10]->size == 0){
                    queue[10]->rearp = (queue_node_t *)malloc (sizeof(queue_node_t));
                    queue[10]->frontp = queue[10]->rearp;
                } else {
                    queue[10]->rearp->restp = (queue_node_t *)malloc(sizeof(queue_node_t));
                    queue[10]->rearp = queue[10]->rearp->restp;
                }
                queue[10]->rearp = queue[i]->rearp;
                queue[10]->size += queue[i]->size;
            }
        }
        queue[10]->rearp = radixSort(queue[10]->rearp, queue, size);
    } else {
                // I used switch statement to handle least significant digit
        switch(curNum%10){
        case 0:
            if(queue[0]->size == 0){
                queue[0]->rearp = (queue_node_t *)malloc (sizeof(queue_node_t));
                queue[0]->frontp = queue[0]->rearp;
            } else {
                queue[0]->rearp->restp = (queue_node_t *)malloc(sizeof(queue_node_t));
                queue[0]->rearp = queue[0]->rearp->restp;
            }
            ++(queue[0]->size);
            queue[0]->rearp->element = curNodep->element;
            queue[0]->rearp->restp = NULL;
            radixSort(curNodep->restp, queue, size);
            break;
        case 1:
            if(queue[1]->size == 0){
                queue[1]->rearp = (queue_node_t *)malloc (sizeof(queue_node_t));
                queue[1]->frontp = queue[0]->rearp;
            } else {
                queue[1]->rearp->restp = (queue_node_t *)malloc(sizeof(queue_node_t));
                queue[1]->rearp = queue[1]->rearp->restp;
            }
            ++(queue[1]->size);
            queue[1]->rearp->element = curNodep->element;
            queue[1]->rearp->restp = NULL;
                        // I tried to make recursion but I guess this is one the problems
            radixSort(curNodep->restp, queue, size);
            break;
        case 2:
            if(queue[2]->size == 0){
                queue[2]->rearp = (queue_node_t *)malloc (sizeof(queue_node_t));
                queue[2]->frontp = queue[2]->rearp;
            } else {
                queue[2]->rearp->restp = (queue_node_t *)malloc(sizeof(queue_node_t));
                queue[2]->rearp = queue[2]->rearp->restp;
            }
            ++(queue[2]->size);
            queue[2]->rearp->element = curNodep->element;
            queue[2]->rearp->restp = NULL;
            radixSort(curNodep->restp, queue, size);
            break;
        case 3:
            if(queue[3]->size == 0){
                queue[3]->rearp = (queue_node_t *)malloc (sizeof(queue_node_t));
                queue[3]->frontp = queue[3]->rearp;
            } else {
                queue[3]->rearp->restp = (queue_node_t *)malloc(sizeof(queue_node_t));
                queue[3]->rearp = queue[3]->rearp->restp;
            }
            ++(queue[3]->size);
            queue[3]->rearp->element = curNodep->element;
            queue[3]->rearp->restp = NULL;

            queue[10]->rearp = radixSort(curNodep->restp, queue, size);
            break;
        case 4:
            if(queue[4]->size == 0){
                queue[4]->rearp = (queue_node_t *)malloc (sizeof(queue_node_t));
                queue[4]->frontp = queue[4]->rearp;
            } else {
                queue[4]->rearp->restp = (queue_node_t *)malloc(sizeof(queue_node_t));
                queue[4]->rearp = queue[4]->rearp->restp;
            }
            ++(queue[4]->size);
            queue[4]->rearp->element = curNodep->element;
            queue[4]->rearp->restp = NULL;
            radixSort(curNodep->restp, queue, size);
            break;
        case 5:
            if(queue[5]->size == 0){
                queue[5]->rearp = (queue_node_t *)malloc (sizeof(queue_node_t));
                queue[5]->frontp = queue[5]->rearp;
            } else {
                queue[5]->rearp->restp = (queue_node_t *)malloc(sizeof(queue_node_t));
                queue[5]->rearp = queue[5]->rearp->restp;
            }
            ++(queue[5]->size);
            queue[5]->rearp->element = curNodep->element;
            queue[5]->rearp->restp = NULL;

            radixSort(curNodep->restp, queue, size);
            break;
        case 6:
            if(queue[6]->size == 0){
                queue[6]->rearp = (queue_node_t *)malloc (sizeof(queue_node_t));
                queue[6]->frontp = queue[6]->rearp;
            } else {
                queue[6]->rearp->restp = (queue_node_t *)malloc(sizeof(queue_node_t));
                queue[6]->rearp = queue[6]->rearp->restp;
            }
            ++(queue[6]->size);
            queue[6]->rearp->element = curNodep->element;
            queue[6]->rearp->restp = NULL;

            radixSort(curNodep->restp, queue, size);
            break;
        case 7:
            if(queue[7]->size == 0){
                queue[7]->rearp = (queue_node_t *)malloc (sizeof(queue_node_t));
                queue[7]->frontp = queue[7]->rearp;
            } else {
                queue[7]->rearp->restp = (queue_node_t *)malloc(sizeof(queue_node_t));
                queue[7]->rearp = queue[7]->rearp->restp;
            }
            ++(queue[7]->size);
            queue[7]->rearp->element = curNodep->element;
            queue[7]->rearp->restp = NULL;

            radixSort(curNodep->restp, queue, size);
            break;
        case 8:
            if(queue[8]->size == 0){
                queue[8]->rearp = (queue_node_t *)malloc (sizeof(queue_node_t));
                queue[8]->frontp = queue[8]->rearp;
            } else {
                queue[8]->rearp->restp = (queue_node_t *)malloc(sizeof(queue_node_t));
                queue[8]->rearp = queue[8]->rearp->restp;
            }
            ++(queue[8]->size);
            queue[8]->rearp->element = curNodep->element;
            queue[8]->rearp->restp = NULL;

            radixSort(curNodep->restp, queue, size);
            break;
        case 9:
            if(queue[9]->size == 0){
                queue[9]->rearp = (queue_node_t *)malloc (sizeof(queue_node_t));
                queue[9]->frontp = queue[9]->rearp;
            } else {
                queue[9]->rearp->restp = (queue_node_t *)malloc(sizeof(queue_node_t));
                queue[9]->rearp = queue[9]->rearp->restp;
            }
            ++(queue[9]->size);
            queue[9]->rearp->element = curNodep->element;
            queue[9]->rearp->restp = NULL;

            radixSort(curNodep->restp, queue, size);
            break;
        }
    }

    return queue[10]->rearp;
}

Редактировать 1 (некоторый прогресс)

Я последовал советам Уильяма Морриса. Мне пришлось задать тот же вопрос на CodeReview, и он дал мне несколько инструкций, чтобы сделать мой код более понятным.

Я разделил свою функцию на функции, а также перестал использовать рекурсию.

Во-первых, я создал функцию add_to_q, которая добавляет значение в связанную очередь, и это помогло избавиться от дублирования кода. Кстати, способ Джеймса Хури самый простой, но он опять же использует рекурсию.

void add_to_q(queue_t *queue_arr[], int value, int pos) {
if(queue_arr[pos]->size == 0){
    queue_arr[pos]->rearp = (queue_node_t *)malloc (sizeof(queue_node_t));
    queue_arr[pos]->frontp = queue_arr[pos]->rearp;
} else {
    queue_arr[pos]->rearp->restp = (queue_node_t *)malloc(sizeof(queue_node_t));
    queue_arr[pos]->rearp = queue_arr[pos]->rearp->restp;
}
queue_arr[pos]->rearp->element = value;
queue_arr[pos]->size++;
}

Во-вторых я создал другие вспомогательные функции. Одним из них является add_to_eleventh, который просто добавляет все элементы очереди в конец одиннадцатой очереди. На мой взгляд, он делает то, что хочет вопрос.

queue_t * add_to_eleventh(queue_t *queue[]) {
int i;
for(i=0;i<=9;i++){
    while(queue[i]->frontp != NULL){
        if(queue[10]->size == 0){
            queue[10]->rearp = (queue_node_t *)malloc (sizeof(queue_node_t));
            queue[10]->frontp = queue[10]->rearp;
        } else {
            queue[10]->rearp->restp = (queue_node_t *)malloc(sizeof(queue_node_t));
            queue[10]->rearp = queue[10]->rearp->restp;
        }
        if ( queue[i]->size != 0 ){
            queue[10]->rearp->element = queue[i]->frontp->element;
            printf("---%d***",queue[i]->frontp->element);
        }
        queue[10]->size+=1;
        queue[i]->frontp = queue[i]->frontp->restp;
        queue[10]->rearp->restp = NULL;
    }
}
return queue[10];
}

В-третьих, моя последняя вспомогательная функция — back_to_ints. Его цель — взять элементы в 11-й очереди, разделить их на десять и вернуть их в виде целочисленного массива.

void back_to_ints(queue_t *arr[], int *new_arr) {
queue_node_t *cur_nodep;
cur_nodep = arr[10]->frontp;
int i = 0, digit;
while(cur_nodep != NULL){
    cur_nodep->element/=10;
    digit = cur_nodep->element / 10;
    new_arr[i++] = digit;
    cur_nodep = cur_nodep->restp;
}
}

Наконец моя новая функция сортировки, которая теперь сортирует целые числа по одной и той же цифре. Таким образом, числа [7] = {112 133 122 334 345 447 346};

queue_t * radix_sort(int *arr, const int size,queue_t *sorted_arr[]) {
int i, digit[size], initials[size],j;
for(i=0;i<size;i++)
    initials[i] = arr[i];
i = 0;
while(initials[i] != 0){
    j = i;
    printf("initialssss%d", initials[--j]);
    back_to_ints(sorted_arr, initials);

    for(i=0;i<size;i++){
    digit[i] = initials[i] % 10;

    switch (digit[i]) {
    case 0:
        add_to_q(sorted_arr, arr[i], 0);
        break;
    case 1:
        add_to_q(sorted_arr, arr[i], 1);
        break;
    case 2:
        add_to_q(sorted_arr, arr[i], 2);
        break;
    case 3:
        add_to_q(sorted_arr, arr[i], 3);
        break;
    case 4:
        add_to_q(sorted_arr, arr[i], 4);
        break;
    case 5:
        add_to_q(sorted_arr, arr[i], 5);
        break;
    case 6:
        add_to_q(sorted_arr, arr[i], 6);
        break;
    case 7:
        add_to_q(sorted_arr, arr[i], 7);
        break;
    case 8:
        add_to_q(sorted_arr, arr[i], 8);
        break;
    case 9:
        add_to_q(sorted_arr, arr[i], 9);
        break;
        }
    }
    sorted_arr[10] = add_to_eleventh(sorted_arr);
    i++;
}
return sorted_arr[10];
}

Я частично решил вопрос. Если вы хотите отсортировать числа по одной и той же цифре, это работает. В противном случае это не удается. Например, если вы ввели 112 133 122 334 345 447 346, то результатом будет 112 122 133 334 345 346 447. Но если пользователь хочет отсортировать что-то подобное (111,13,12,334,345,447,1), он дает 111 1 12 13 334 345 447. Итак, как я могу победить эту проблему.

Кроме того, я немного изменил свой заголовочный файл.

#ifndef RADIX_H_
#define RADIX_H_

typedef struct queue_node_s {
    int element;
    struct queue_node_s *restp;
}queue_node_t;

typedef struct {
    queue_node_t *frontp,
             *rearp;
    int size;
}queue_t;

queue_t * radix_sort(int *arr,const int size, queue_t *sorted_arr[]);
void add_to_q(queue_t *queue_arr[], int value, int pos);
queue_t * add_to_eleventh(queue_t *queue[]);
void back_to_ints(queue_t *arr[], int *new_arr);
void displayRadixed(queue_t *sorted[]);
#endif /* RADIX_H_ */

Спасибо, что снова открыли мою тему...


person mustafaSarialp    schedule 05.10.2012    source источник
comment
Почему вы хотите использовать очередь для сортировки по основанию? Кроме того, является ли/должна ли это быть очередь с приоритетом или обычная очередь?   -  person anatolyg    schedule 05.10.2012
comment
@anatolyg Это вопрос из книги, и он хочет решить этот вопрос с помощью очереди. Я понятия не имею для вашего второго вопроса. Может нормальная очередь...   -  person mustafaSarialp    schedule 05.10.2012
comment
Этот вопрос относится к codereview.stackexchange.com.   -  person Doug Currie    schedule 05.10.2012
comment
@DougCurrie, этот вопрос не относится к проверке кода   -  person James Khoury    schedule 22.10.2012
comment
@mustafaSarialp Я отредактировал ваш вопрос, чтобы попытаться сделать его более ясным. Пожалуйста, дайте мне знать, если есть потеря смысла.   -  person James Khoury    schedule 22.10.2012
comment
Спасибо @JamesKhoury. Я не мог объяснить свою проблему так ясно, как это.   -  person mustafaSarialp    schedule 22.10.2012
comment
@mustafaSarialp Было бы также полезно, если бы вы могли объяснить, какой результат вы ожидаете увидеть и какой результат вы фактически видите, с примерами данных.   -  person James Khoury    schedule 22.10.2012
comment
@JamesKhoury Я добавил то, что вы предлагаете. Надеюсь, я смог сделать это правильно.   -  person mustafaSarialp    schedule 22.10.2012
comment
@DougCurrie: для дальнейшего использования. Нет, это не относится к просмотру кода. Сайт проверки кода предназначен для работы кода, чтобы сделать его лучше. Stackoverflow предназначен для получения ответов на вопрос, когда код не работает.   -  person Martin York    schedule 22.10.2012
comment
Посмотрите это, чтобы ознакомиться с реализацией :) youtube.com/watch?v=xhr26ia4k38< /а>   -  person Hong Zhou    schedule 02.11.2012


Ответы (4)


Я немного изменил вашу очередь. Чтобы лучше понять код, я использую переднюю и заднюю части как глобальные переменные.

typedef struct queue *queue_ptr;
        struct queue {
               int data;
               queue_ptr next;
        };
queue_ptr front[10], rear[10];  /* For base 10, The 11th queue is not needed */

Таким образом, операция добавления в очередь становится

void add_queue(int i, int data) {
        queue_ptr tmp;

        tmp = (queue_ptr) malloc(sizeof(*tmp));
        tmp->next = NULL;
        tmp->data = data;
        if (front[i]) {
                rear[i]->next = tmp;
        } else {
                front[i] = tmp;
        }   
        rear[i] = tmp;
}

И добавить операцию удаления из очереди (также вернуть данные)

int delete_queue(int i) {
        int data;
        queue_ptr tmp;

        tmp = front[i];
        if (!tmp) {
                return -1;  /* So that we can check if queue is empty */
        }   
        data = tmp->data;
        front[i] = tmp->next;
        free(tmp);
        return data;
}

Итак, теперь мы можем реализовать сортировку по основанию. Возможно, будет проще переместить ваши данные в очередь с фактическими числами, а не с одной цифрой. Обратите внимание, что 11-я очередь не нужна, если вы можете изменить свой тестовый массив *arr, и ваша функция radix_sort может быть такой:

void radix_sort(int *arr, const int size) {
        int i, j, k, radix, digits, tmp;

        if (size < 1) {
                return;  /* don't do anything if invalid size */
        }

        /* get the number of digits */
        for (digits = 0, radix = 1; arr[0] >= radix; digits++, radix *= 10);

        /* perform sort (digits) times from LSB to MSB */
        for (i = 0, radix = 1; i < digits; i++, radix *= 10) {
                /* distribute into queues */
                for (j = 0; j < size; j++) {
                        add_queue((arr[j] / radix) % 10, arr[j]);
                }
                /* take them out from each queue to the original test array */
                for (j = 0, k = 0; j < 10; j++) {
                        for (tmp = delete_queue(j); tmp != -1;\
                             tmp = delete_queue(j), k++) {
                                arr[k] = tmp;
                        }
                }
        }
}

И, наконец, вы можете протестировать, вызвав radix_sort(your_array, your_array_size), полный код

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

typedef struct queue *queue_ptr;
        struct queue {
               int data;
               queue_ptr next;
        };

queue_ptr front[10], rear[10];  /* For base 10, The 11th queue is not needed */

void add_queue(int i, int data) {
        queue_ptr tmp;

        tmp = (queue_ptr) malloc(sizeof(*tmp));
        tmp->next = NULL;
        tmp->data = data;
        if (front[i]) {
                rear[i]->next = tmp;
        } else {
                front[i] = tmp;
        }
        rear[i] = tmp;
}

int delete_queue(int i) {
        int data;
        queue_ptr tmp;

        tmp = front[i];
        if (!tmp) {
                return -1;  /* So that we can check if queue is empty */
        }
        data = tmp->data;
        front[i] = tmp->next;
        free(tmp);
        return data;
}

void radix_sort(int *arr, const int size) {
        int i, j, k, radix, digits, tmp;

        if (size < 1) {
                return;  /* don't do anything if invalid size */
        }

        /* get the number of digits */
        for (digits = 0, radix = 1; arr[0] >= radix; digits++, radix *=10);

        /* perform sort (digits) times from LSB to MSB */
        for (i = 0, radix = 1; i < digits; i++, radix *= 10) {
                /* distribute to queues */
                for (j = 0; j < size; j++) {
                        add_queue((arr[j] / radix) % 10, arr[j]);
                }
                /* take them out from each queue to the original test array */
                for (j = 0, k = 0; j < 10; j++) {
                        for (tmp = delete_queue(j); tmp != -1;\
                             tmp = delete_queue(j), k++) {
                                arr[k] = tmp;
                        }
                }
        }
}

int main(void) {
        int i;
        int a[5] = {133, 34, 555, 111, 12},
            b[12] = {1, 1, 1, 4, 5, 6, 7, 8, 9, 11, 11, 12};

        radix_sort(a, 5);
        radix_sort(b, 5);

        for (i = 0; i < 5; i++) {
                printf("%d ", a[i]);
        }
        printf("\n");

        for (i = 0; i < 12; i++) {
                printf("%d ", b[i]);
        }
        printf("\n");

        return 0;
}

и выход

12 34 111 133 555
1 1 1 4 5 6 7 8 9 11 11 12
person ylc    schedule 05.11.2012
comment
Я думаю, что порядок должен быть 12 111 133 34 555 и 1 1 1 11 11 12 4 5 6 7 8 9 - person James Khoury; 06.11.2012
comment
Первым должен быть 111 12 133 34 555 Извините. - person James Khoury; 06.11.2012
comment
@JamesKhoury Почему? 111‹12 или 12‹4? - person ylc; 06.11.2012
comment
Да, на странице приведен пример чуть ниже определения. Все цифры всегда отсортированы. Так, например, 170 и 75 сортируются по разряду сотен и становятся 75 ‹ 170, так как 075 ‹ 170. - person ylc; 06.11.2012
comment
это для сортировки по наиболее значимой цифре. ОП просил сортировку по наименьшей значимости. - person James Khoury; 06.11.2012
comment
Нет. Я имел в виду последний проход сортировки по основанию LSD. Пример на вики: 170, 45, 75, 90, 802, 24, 2, 66 --(сортировка по 1-му разряду)--> 170, 90, 802, 2, 24, 45, 75, 66 --(сортировка по 10-му разряду) место) --> 802, 2, 24, 45, 66, 170, 75, 90 --(сортировка по разряду 100) --> 2, 24, 45, 66, 75, 90, 170, 802. 170 и 075 отсортированы после последнего прохода. ОП пытался преодолеть, почему он / она получил ложный вывод 111 1 12 13 334 345 447, а отсортированный массив должен быть 1 12 13 111 334 345 447. - person ylc; 06.11.2012
comment
Думаю, теперь я тебя понимаю. Я думаю, что неправильно читал ваш код. Теперь я действительно скомпилировал и протестировал ваш код. - person James Khoury; 06.11.2012

Некоторая хорошая информация здесь уже. На более высоком уровне будет сложно отлаживать ваш код, потому что он сложнее, чем должен быть. Ниже приведен другой код, использующий C для выражения алгоритма в более идиоматичном стиле.

Общий смысл в том, что когда дело доходит до кода, обычно меньше значит больше: простота — ваш друг. Особенности, показанные здесь:

  1. Циклические односвязные списки для очередей. Очередь — это указатель на конечный узел списка. При этом добавление и объединение являются быстрыми операциями с постоянным временем.
  2. Логическая многоразовая функциональная декомпозиция.
  3. Всего около 80 SLOC, включая простой тест. Функция сортировки — 18 SLOC.
  4. Слегка протестировано.

Вот такой:

// Radix sort the given queue.
void sort(QUEUE *queue)
{
  unsigned i, j, div;
  QUEUE queues[RADIX], accum;

  // Handle case of nothing to sort.
  if (*queue == NULL) return;

  // Accumulator queue initially holds unsorted input.
  accum = *queue;

  // Make one pass per radix digit.
  for (i = 0, div = RADIX; i < MAX_DIGITS; i++, div *= RADIX) {

    // Clear the radix queues.
    for (j = 0; j < RADIX; j++) queues[j] = NULL;

    // Append accumulator nodes onto radix queues based on current digit.
    NODE *p = accum, *p_next = p->next;
    do {
      // Save p->next here because append below will change it.
      p = p_next; p_next = p->next;
      append_node(&queues[p->val / div % RADIX], p);
    } while (p != accum);

    // Gather all the radix queues into the accumulator again.
    for (accum = NULL, j = 0; j < RADIX; j++) cat(&accum, queues[j]);
  }
  // Accumulator now holds sorted input.
  *queue = accum;
}

И остальное:

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

#define RADIX 10
#define MAX_DIGITS 9

// Node and circular queue. A queue is either null or a pointer to the _tail_ node.
typedef struct node_s {
  struct node_s *next;
  unsigned val;
} NODE, *QUEUE;

// Make a new node with given value.
NODE *new_node(unsigned val)
{
  NODE *node = calloc(1, sizeof *node);
  // Must trap null return value here in production code!
  node->val = val;
  return node;
}

// Append given node to the tail of a queue.
void append_node(QUEUE *queue, NODE *node)
{
  NODE *tail = *queue;
  if (tail) {
    node->next = tail->next;
    tail->next = node;
  }
  else {
    node->next = node;
  }
  *queue = node;
}

// Concatenate the second queue onto the tail of the first. 
// First queue is changed (because it's a pointer to a tail node).
void cat(QUEUE *a, QUEUE b_tail)
{
  NODE *a_tail, *a_head;

  if (b_tail == NULL) return;
  a_tail = *a;
  if (a_tail) {
    a_head = a_tail->next;
    a_tail->next = b_tail->next;
    b_tail->next = a_head;
  }
  *a = b_tail;
}
// Sort code above goes here if you're compiling it.
// And test main goes here.

Небольшой основной тест:

int main(void)
{
  int i;
  unsigned data[] = { 98, 111, 42, 1111, 21 , 997, 0, 99999, 20903};

  // Make a queue from data.
  QUEUE a = NULL;
  for (i = 0; i < sizeof data / sizeof data[0]; i++)
    append_node(&a, new_node(data[i]));

  sort(&a);

  // Print the circular list.
  NODE *p = a;
  do {
    p = p->next;
    printf("%u\n", p->val);
  } while (p != a);

  return 0;
}
person Gene    schedule 07.11.2012
comment
+1 Хотя мне нравится этот код, я чувствую себя обязанным прокомментировать, что меньше строк кода не всегда лучше. - person James Khoury; 07.11.2012
comment
Конечно, ты прав. На самом деле все дело в простоте, как сказал Эйнштейн: максимально просто, но не проще. В программировании простые структуры данных, простые алгоритмы, простые идиомы проще всего поддерживать и часто быстрее всего. Проще, как правило, но не всегда означает короче, поэтому я сказал обычно. - person Gene; 07.11.2012

Отказ от ответственности: я еще не реализовал сортировку по основанию и не тестировал приведенный ниже код. Я оставлю это вам в качестве упражнения.

Когда вы обнаружите, что копируете что-то более одного раза, остановитесь и подумайте: должен быть шаблон.

В вашем операторе switch много копий и вставок. В case 1: у вас есть строка:

queue[1]->frontp = queue[0]->rearp;

Я предполагаю, что это должно быть:

queue[1]->frontp = queue[1]->rearp;

Если бы вы реорганизовали этот код, вы могли бы увидеть это проще?

Как насчет замены всего оператора switch на:

int leastSignificantDigit = curNum%10;

if(queue[leastSignificantDigit]->size == 0){
    queue[leastSignificantDigit]->rearp = (queue_node_t *)malloc (sizeof(queue_node_t));
    queue[leastSignificantDigit]->frontp = queue[leastSignificantDigit]->rearp;
} else {
    queue[leastSignificantDigit]->rearp->restp = (queue_node_t *)malloc(sizeof(queue_node_t));
    queue[leastSignificantDigit]->rearp = queue[leastSignificantDigit]->rearp->restp;
}
++(queue[leastSignificantDigit]->size);
queue[leastSignificantDigit]->rearp->element = curNodep->element;
queue[leastSignificantDigit]->rearp->restp = NULL;
radixSort(curNodep->restp, queue, size);
person James Khoury    schedule 23.10.2012

Проблема, которую я увидел в первом примере кода, заключается в том, что

curNum = curNodep->element.key

curNum всегда имеет полное число, а оператор switch всегда делает curNum % 10, и это только проверка последней цифры.

В вашем рекурсивном решении (рекурсия не является проблемой) вы должны передать параметр, чтобы узнать, какая цифра должна иметь дело.

Я знаю эту технику как погружение.

Если вы видите образцы, которые вы поместили в конце ответа, вы увидите, что последняя цифра является порядком, вы можете изменить входные образцы, чтобы лучше это видеть. Добавьте большие числа с маленькой последней цифрой, например, «901», и посмотрите результат.

Извините за мой английский...

person Carlos    schedule 05.11.2012
comment
Не могли бы вы предоставить код, чтобы показать предложенное вами решение? - person James Khoury; 06.11.2012