首页 > 解决方案 > 我写了一个函数来删除循环链接列表中的第一个节点,但输出显示无限次“55 44 33 22 11 99”,那我该如何解决?

问题描述

我检查了我的显示功能,它工作得很好。但是我的下面的功能不能正常工作。最初的列表有“ 66 55 44 33 22 11”

void deleteFOdd(struct Node*head)
{
    struct Node* last=head,*t=head;
    while(last->next!=head)
    {
        last=last->next;
    }

    last->next=t->next;
    head=t->next;
    free(t);
}

我不明白为什么在删除第一个节点后它的打印数组无限次。

标签: c++cdata-structures

解决方案


正如H.cohen在评论中指出的那样,head在函数中本地更改参数对函数外部的值没有影响。您需要以某种方式将更新的头部传回给调用者。正如Jonathan Leffler所建议的那样,这可以通过返回更新的头指针(调用者需要将其存储在某个地方,可能在传递给函数的同一变量中)来完成,或者可以将函数参数更改为指针指向头部的指针。

方法 1 - 返回新的头部

struct Node* deleteFOdd(struct Node*head)
{
    struct Node* last=head,*t=head;
    while(last->next!=head)
    {
        last=last->next;
    }

    last->next=t->next;
    head=t->next;
    free(t);
    return head;
}

上面的代码中有一个错误,因为它不处理包含单个元素的列表的情况。我建议NULL在这种情况下返回。head此外,如果函数检查是否NULL在开始时会很好。这是一个修改后的版本:

struct Node* deleteFOdd(struct Node*head)
{
    struct Node* last=head,*t=head;
    // optional: deal with NULL list
    if (head==NULL)
    {
        return head;
    }
    while(last->next!=head)
    {
        last=last->next;
    }
    if (last==head)
    {
        // list contained only 1 element
        head=NULL;
    }
    else
    {
        last->next=t->next;
        head=t->next;
    }
    free(t);
    return head;
}

调用者可以按如下方式调用该函数:

head = deleteFOdd(head);

方法 2 - 将指针传递给头指针

下面是在上面的修改版本的基础上,但是使用了一个指向指针的指针来传回更新后的头指针。

void deleteFOdd(struct Node** headp)
{
    struct Node* head=*headp;
    struct Node* last=head,*t=head;
    // optional: deal with NULL list
    if (head==NULL)
    {
        return;
    }
    while(last->next!=head)
    {
        last=last->next;
    }
    if (last==head)
    {
        // list contained only 1 element
        head=NULL;
    }
    else
    {
        last->next=t->next;
        head=t->next;
    }
    free(t);
    *headp = head;
}

调用者可以按如下方式调用该函数:

deleteFOdd(&head);

推荐阅读