C中的通用链表排序功能

时间:2014-12-13 17:02:28

标签: c sorting linked-list

我正在尝试对节点的链接列表进行排序。我查看列表中的每个节点,将其与当前头部进行比较,如果它“更大”则交换。最后,我发现head->next。 我希望函数返回新排序函数的“head”。

第一个问题是它似乎陷入了第一个for循环。

我哪里出错?

struct Node{
    char firstName[50];
    char lastName[50];
    int age;
    struct Node *next;
};

struct Node * sortList(struct Node * head, 
    int(*cmp)(struct Node *, struct Node *)){
    printf("Entered Sorting Function\n");
    struct Node * target;
    struct Node * p;
    struct Node * first;
    bool firstRun = TRUE;
    target=head;
    first=head;
    for (p=head; p!=NULL; p=p->next) {
        if ((*cmp)(p, target) == 1)
            printf("Comparing %s with %s\n", p->firstName, target->firstName);
            target = p;
    }
    if (head!=target) {
        printf("swapping nodes");
        swapNodes(head, target);
    }
    if (firstRun==TRUE) {
        first = head;
        printf("setting very first to: %s\n", first->firstName);
        firstRun = FALSE;
    }
    if (target->next != NULL) {
        printf("recurring with %s\n", target->next->firstName);
        sortList(target->next, cmp);
    }
    return first;
}

更新

第一个循环中的问题是if中的语句缺少大括号,正如nemetroid answer所指出的那样 - 谢谢,nemetroid。代码应为:

    for (p=head; p!=NULL; p=p->next) {
        if ((*cmp)(p, target) == 1) {
            printf("Comparing %s with %s\n", p->firstName, target->firstName);
            target = p;
        }
    }

但是,排序仍然不起作用。还有什么不对?

我发现我的交换不起作用,正如人们提到的那样。这是包含交换的更新代码。

更新:我修复了交换,现在我只交换了节点的内容。

void swapNodes(struct Node * nodeA, struct Node * nodeB) {
    struct Node * tmp = malloc(sizeof(struct Node));
    strcpy(tmp->firstName, nodeA->firstName);
    strcpy(tmp->lastName, nodeA->lastName);
    tmp->age = nodeA->age;

    strcpy(nodeA->firstName, nodeB->firstName);
    strcpy(nodeA->lastName, nodeB->lastName);
    nodeA->age = nodeB->age;

    strcpy(nodeB->firstName, tmp->firstName);
    strcpy(nodeB->firstName, tmp->firstName);
    nodeB->age = tmp->age;
}

但是排序仍然不起作用,这是我的排序的当前代码:

void sortList(struct Node * head, 
    int(*cmp)(struct Node *, struct Node *)){
        if (head==NULL || head->next==NULL)
            return;
        int length = listLength(head);
        int i, j;
        struct Node * p = head;
        struct Node * q = p;
        bool firstRun = TRUE;
        for (i=0; i<length; i++) {
            if (firstRun != TRUE) 
                p=p->next;
            else if (firstRun == TRUE)
                firstRun = FALSE;
            for (j=i+1; j<length-1; j++) {
                q = q->next;
                if ((*cmp)(q, p) == 1) 
                    swapNodes(p, q);
            }
        }

}

我修好了。在答案中发布排序代码。感谢大家的帮助。

2 个答案:

答案 0 :(得分:2)

因为if语句缺少括号,只有printf("Comparing...是有条件的,所以你在for循环的每次迭代中执行target = p。这可能不是你打算做的。

此外,您可能希望first = target而不是head。虽然整个块都是可疑的,它会在每个递归步骤中运行。

答案 1 :(得分:1)

这是我使用的代码,它似乎到目前为止工作。 注意:我们通过交换它们的内容交换2个节点,而不操纵它们指向下一个元素。

void sortList(struct Node * head, 
    int(*cmp)(struct Node *, struct Node *)){
        if (head==NULL || head->next==NULL)
            return;
        int length = listLength(head);
        int i, j;
        struct Node * p = head;
        struct Node * q = p;
        struct Node * target = head;
        bool firstRun = TRUE;
        for (i=0; i<length; i++) {
            q=p;
            if (firstRun != TRUE) 
                p=p->next;
            else if (firstRun == TRUE) 
                firstRun = FALSE;
            target = p;
            while (q->next != NULL) {
                q = q->next;
                if ((*cmp)(q, target) < 0) 
                    target = q;
            }
            if (p!=target)
                swapNodes(p, target);   
        }
}