C 意外遍历链表

C 意外遍历链表,c,linked-list,C,Linked List,我很难弄清楚为什么我的链表不能正确地“访问节点”。我的代码似乎比我想要的要晚一步。被访问的节点仅在添加第三个节点后才开始堆叠,而第二个节点应在添加第二个节点后堆叠。对我来说,这个逻辑应该可以工作,因为当第一个节点被创建,第二个节点被初始化为NULL时,while不会命中,也不会打印任何内容。然后创建第二个节点并将其添加到列表的末尾,第三个节点现在为空。当我们在这个迭代中循环时,它应该打印第一个节点,因为temp->next在第一个节点处不为NULL 不确定我在这里没有看到什么。我的逻辑哪里错了

我很难弄清楚为什么我的链表不能正确地“访问节点”。我的代码似乎比我想要的要晚一步。被访问的节点仅在添加第三个节点后才开始堆叠,而第二个节点应在添加第二个节点后堆叠。对我来说,这个逻辑应该可以工作,因为当第一个节点被创建,第二个节点被初始化为NULL时,while不会命中,也不会打印任何内容。然后创建第二个节点并将其添加到列表的末尾,第三个节点现在为空。当我们在这个迭代中循环时,它应该打印第一个节点,因为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
waitList*temp=*head;
while(临时->下一步!=NULL)
{
printf(“使用值%d和%d访问节点%s\n”,temp->name,temp->numBurgers,temp->numSalads);
温度=温度->下一步;
}
获取列表中的第一个元素(*head),然后检查其
next
是否为空

将第一个元素添加到列表后,有一个元素(head),第二个元素尚未添加

waitList*temp=*head;
而(1)
{            
printf(“使用值%d和%d访问节点%s\n”,temp->name,temp->numBurgers,temp->numSalads);
如果(临时->下一步==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;
    }
}


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

有很多方法可以解决这个问题。这里有一个我喜欢的:

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;

。。。然后,你不再需要第一个节点的特殊情况。

虽然<代码>新< /C> >不是C关键字,它是C++关键字。因为把C代码转换成C++是一个有时做的事情,我建议避免使用<代码>新< /代码>作为标识符C。此外,我也建议无论如何选择一个更具体的标识符,例如<代码> NealList。