【问题标题】:Unexpected traversal of linked list链表意外遍历
【发布时间】:2021-02-13 07:28:10
【问题描述】:

我无法弄清楚为什么我的链接列表没有正确“访问节点”。看来我的代码比我想要的要落后一步。被访问的节点只有在添加第三个节点后才开始堆叠,而应该在添加第二个节点后才开始堆叠。对我来说,这个逻辑应该起作用,因为当第一个节点被创建并且第二个被初始化为 NULL 时,while 没有命中并且没有打印任何内容,这对我来说是有意义的。然后创建第二个节点并将其添加到列表的末尾,第三个节点现在为 NULL。当我们循环这个迭代时,它应该打印第一个节点,因为 temp->next 在第一个节点处不是 NULL。

不确定我在这里没有看到什么。我的逻辑哪里错了?


void addToList(waitList** head, char *name, int numBurgers, int numSalads)
{
    waitList *new = (waitList*) malloc (sizeof(waitList));
    new->name = name;
    new->numBurgers = numBurgers;
    new-> numSalads = numSalads;

    new-> next = NULL;

    if(*head == NULL)
    {
        *head = new;
    }
    else
    {
        waitList *temp = *head;

        while(temp->next != NULL )
        {
            
            
            printf("Visiting node %s with values %d and %d\n", temp->name, temp->numBurgers, temp->numSalads);
            
            temp = temp-> next;
        }

        temp->next = new;
    }
}


我得到的输出:

Enter command: a 3 3 nick
Adding In-restaurant order for "nick": 3 burgers and 3 salads

Enter command: a 4 4 bob
Adding In-restaurant order for "bob": 4 burgers and 4 salads

Enter command: a 6 6 kevin
Adding In-restaurant order for "kevin": 6 burgers and 6 salads
Visiting node nick with values 3 and 3

Enter command: a 9 9 max
Adding In-restaurant order for "max": 9 burgers and 9 salads
Visiting node nick with values 3 and 3
Visiting node bob with values 4 and 4

预期输出:

Enter command: a 3 3 nick
Adding In-restaurant order for "nick": 3 burgers and 3 salads

Enter command: a 4 4 bob
Adding In-restaurant order for "bob": 4 burgers and 4 salads
Visiting node nick with values 3 and 3

Enter command: a 6 6 kevin
Adding In-restaurant order for "kevin": 6 burgers and 6 salads
Visiting node nick with values 3 and 3
Visiting node bob with values 4 and 4

Enter command: a 9 9 max
Adding In-restaurant order for "max": 9 burgers and 9 salads
Visiting node nick with values 3 and 3
Visiting node bob with values 4 and 4
Visiting node kevin with values 6 and 6

【问题讨论】:

  • 虽然new 不是C 关键字,但它 一个C++ 关键字。由于有时需要将代码从 C 转换为 C++,因此我建议避免使用 new 作为标识符 C。此外,我还建议选择更具体的标识符,例如 newList

标签: c linked-list


【解决方案1】:
        waitList *temp = *head;

        while(temp->next != NULL )
        {
            
            
            printf("Visiting node %s with values %d and %d\n", temp->name, temp->numBurgers, temp->numSalads);
            
            temp = temp-> next;
        }

您获取列表中的第一个元素 (*head),然后检查其 next 是否为空。

将第一个元素添加到列表后,您有一个元素(头部),而第二个元素尚未添加。

        waitList *temp = *head;

        while(1)
        {            
            printf("Visiting node %s with values %d and %d\n", temp->name, temp->numBurgers, temp->numSalads);
            
            if (temp->next == NULL) {
                break;
            }
            temp = temp-> next;
        }

【讨论】:

    【解决方案2】:

    我的逻辑哪里错了?

    您添加节点的逻辑很好。添加新节点时打印现有节点的逻辑省略了列表中的最后一个节点,因为它只打印满足while 条件temp->next != NULL 的节点。

    有很多方法可以修复它。这是我喜欢的一个:

    waitList dummy = { .next = *head };
    waitList *last = &dummy;
    
    for (waitList *temp = last->next; temp; last = temp, temp = last->next) {
        printf("Visiting node %s with values %d and %d\n", temp->name,
                temp->numBurgers, temp->numSalads);
    }
    
    last->next = new;
    

    这样,当您遍历列表时,temp 指针在当前 last 指针之前运行一个节点,last 开始指向实际头部之前的一个虚拟节点。这样您就可以避免将 last 推进到真正的最后一个节点之外,而 temp 会依次获取指向每个现有节点的值,包括最后一个节点。

    还要注意,如果你添加 ...

    *head = dummy.next;
    

    ...那么您不再需要第一个节点的特殊情况。

    【讨论】:

      猜你喜欢
      • 2017-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-14
      • 2022-01-06
      相关资源
      最近更新 更多