【问题标题】:Generic linked list sorting function in CC中的通用链表排序函数
【发布时间】:2014-12-13 17:02:27
【问题描述】:

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

第一个问题是它似乎卡在了第一个 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);
            }
        }

}

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

【问题讨论】:

  • '我哪里出错了?' - 不调试代码/数据。
  • 请不要通过破解问题使答案无效;更新问题以显示部分修复。这次我会这样做,以说明。
  • 你需要显示swapNodes() 的正文,因为这个调用至少是可疑的:swapNodes(head, target);。通常,您需要将指针传递给要交换的指针,但这确实取决于代码的作用。 firstRun 代码也很可疑;您应该简单地将递归调用的返回值记录在合适的位置(可能是first-&gt;next = sortList(head-&gt;next, cmp);)。
  • 我认为我的交换工作是理所当然的。显然不是。我贴出尸体。 @JonathanLeffler
  • 您的 malloc 和 free 使用非常混乱。每次 malloc 时,您需要精确地释放一次。不过,您的代码也不需要。

标签: c sorting linked-list


【解决方案1】:

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

另外,您可能想要使用first = target 而不是head。不过,整个块的用途很可疑,它会在每个递归步骤中运行。

【讨论】:

  • 这就是它卡在循环中的原因,对。但这不是它不起作用的原因。但我想我可能有一个线索。我处于恐慌模式,是的,压力太大不适合完成。
【解决方案2】:

这是我使用的代码,到目前为止它似乎工作。 注意:我们通过交换它们的内容来交换 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);   
        }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-09
    • 2021-05-24
    • 2013-10-01
    • 2023-04-04
    • 2023-03-08
    • 2017-07-22
    相关资源
    最近更新 更多