开发者

How do I sort a linked list of structures by one of the fields?

开发者 https://www.devze.com 2023-01-29 15:52 出处:网络
Wow now i know I dont. Lol. I\'ve got my structure like this: struct Medico{ int Id_Doctor; int Estado; char Nombre[60]; ////focus on this part of the structure, this is name.

Wow now i know I dont. Lol.

I've got my structure like this:

struct Medico{ 
int Id_Doctor;
int Estado;
char Nombre[60]; ////focus on this part of the structure, this is name.
char Clave_Acceso[20];
char Especialidad[40];
struct Medico *next;
};

And I want to organize the structure depending on the name(alphabetical or开发者_StackOverflow社区der..) any ideas on how to tackle this problem?

for example

Albert Haynesworth
Bob Marley
Carl Johnson

Thank you very much in advanced. :)(C, Unix)


Implementing a mergesort over a linked list in C is quite easy:

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

struct node {
    struct node *next;
    char *data;
};

struct node *
divlist (struct node *n) {
    int i = 0;
    if (n) {
        struct node *tail, *n2 = n;
        while (1) {
            n2 = n2->next;
            if (!n2) break;
            if (i++ & 1) n = n->next;
        }
        tail = n->next;
        n->next = NULL;
        return tail;
    }
    return NULL;
}

struct node *
mergelists(struct node *a, struct node *b) {
    struct node *n;
    struct node **last = &n;
    if (!a) return b;
    if (!b) return a;

    while (1) {
        if (strcmp(a->data, b->data) > 1) {
            *last = b;
            last = &b->next;
            b = b->next;
            if (!b) {
                *last = a;
                break;
            }
        }
        else {
            *last = a;
            last = &a->next;
            a = a->next;
            if (!a) {
                *last = b;
                break;
            }
        }
    }
    return n;
}

struct node *
sortlist (struct node *n) {
    struct node *tail = divlist(n);
    if (!tail) return n;
    return mergelists(sortlist(n), sortlist(tail));
}

int main(int argc, char *argv[]) {
    int i;
    struct node *n1, *n = NULL;
    for (i = argc; --i >= 1;) {
        n1 = (struct node *)malloc(sizeof(*n1));
        n1->data = argv[i];
        n1->next = n;
        n = n1;
    }

    n1 = n = sortlist(n);

    while (n1) {
        printf("%s\n", n1->data);
        n1 = n1->next;
    }
    return 0;
}

Note that you will have to modify this code to use your data structure and the right comparison!


C can't sort for you, nor maintain a sorted data structure. As others have suggested, you need to sort it yourself. I would do this when you create a new Medico, since inserting into a linked list is easy, and you can just find where it belongs as you iterate.

If Medico's order needs to be different, than you will need to sort the list whenever you display it. You'll probably want to iterate to pull out every name, then sort the resultant array using any of a number of techniques (depending on the size).

Assuming the list order is otherwise of no concern, keep it in order.


Sounds like you want to look at implementations of either quicksort or mergesort. I believe that the c std lib qsort implementation takes an array and not a linked list, so you may need to implement your own (although I'm pretty sure that you could find a readily available implementation on the interwebz if you did a quick search)


If you want to sort an array of structures, you can use the qsort function, see man qsort. It takes a base address of the array, number of elements, element size and comparing function:

int compare(const void *a, const void *b) {
    Medico *medA = (Medico*) a;
    Medico *medB = (Medico*) b;
    return /* compare medA and medB */;
}

Medico *medicos = /* initialize */;
qsort(medicos, numberOfMedicos, sizeof(Medico), compare);

D’oh, just now I noticed the next-record pointer that probably makes this answer useless. (I’ve changed the question title to make the linked list apparent.) To make at least something from this answer, you can always copy the list into an array:

Medico *medicos = calloc(sizeof(Medico), numberOfMedicos);
Medico *current = /* first record in your linked list */;
int i = 0;

assert(current);
do {
    medicos[i++] = *current;
    current = current->next;
} while (current);

// Here you can sort the array.

free(medicos);

Of course, it depends on the number of records and other variables.

(My C is a bit rusty, feel free to fix.)

0

精彩评论

暂无评论...
验证码 换一张
取 消