如何按其中一个字段对结构的链接列表进行排序?

时间:2010-12-08 07:19:51

标签: c file-io structure

哇现在我知道我不会。洛尔。

我的结构是这样的:

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;
};

我想根据名称(字母顺序......)组织结构,以解决如何解决这个问题?

例如

Albert Haynesworth
Bob Marley
Carl Johnson

非常感谢您的进步。 :)(C,Unix)

4 个答案:

答案 0 :(得分:1)

C无法为您排序,也无法维护已排序的数据结构。正如其他人所建议的那样,您需要自己进行排序。我会在你创建一个新的Medico时这样做,因为插入链表很容易,你可以在迭代时找到它所属的位置。

如果Medico的订单需要不同,那么每当您显示它时,您需要对列表进行排序。您可能希望迭代以提取每个名称,然后使用多种技术(取决于大小)对结果数组进行排序。

假设列表顺序无关紧要,请保持顺序。

答案 1 :(得分:1)

听起来您想要查看quicksortmergesort的实施。我相信c std lib qsort实现需要一个数组而不是一个链表,所以你可能需要实现自己的(虽然我很确定你可以在interwebz上找到一个现成的实现,如果你做了一个快速搜索)

答案 2 :(得分:1)

在C中的链表上实现mergesort非常简单:

#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;
}

请注意,您必须修改此代码才能使用您的数据结构和正确的比较!

答案 3 :(得分:0)

如果要对结构数组进行排序,可以使用qsort函数,请参阅man qsort。它需要数组的基址,元素数,元素大小和比较函数:

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'哦,刚才我注意到了下一个记录指针可能会让这个答案变得无用。 (我已经更改了问题标题以使链接列表显而易见。)要从这个答案中至少做一些事情,你总是可以将列表复制到一个数组中:

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);

当然,这取决于记录和其他变量的数量。

(我的C有点生疏,随时修理。)