【问题标题】:Difference between linked list traversal **while(thead != NULL)** and while(thead->next !=NULL)链表遍历 **while(thead != NULL)** 和 while(thead->next !=NULL) 的区别
【发布时间】:2017-11-15 18:28:34
【问题描述】:

谁能告诉我 while(thead != NULL)while(thead->next !=NULL) 有什么区别,因为用于遍历列表 thead != NULL 不工作,而 thead->next 工作。 据我了解,头节点只是指向起始节点的指针,而不是起始节点本身。
See this if u have doubt.这里的头只是存储地址。

//thead 表示临时头变量,用于存储头指向的地址。
这是插入的代码。

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>

struct node
{
    int data;
    struct node *next;
};
struct node *head;
void insert(int x)
{
    struct node *temp=(struct node *)malloc(sizeof(struct node));   
    temp->data=x;   
    temp->next=NULL;   
    if(head==NULL)     
    {     
         head=temp;    
    }
    else
    {
        struct node * thead;
        thead=head;  
        while(thead->next!=NULL)
        {
            thead=thead->next;  
        }
        thead->next=temp;
    }
}

void print()
{
    struct node *temp;
    temp=head;
    while(temp!=NULL)
    {

        printf("%d",temp->data);
            temp=temp->next;
    }
}
int main()
{
    head=NULL;
    int i,n,x;
    printf("enter number of nodes");
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        printf("enter no");
        scanf("%d",&x);
        insert(x);
    }
    print();
}

如果我们将 thead ->next != NULL 替换为 thead !=NULL 则 dev c++ 停止工作。反之亦然,在 printf 中进行遍历...

那么有人可以回答上述两者之间的区别吗?

另外,头节点是第一个包含数据和地址的节点,还是只存储上图中的地址?

另外,如果头节点只是一个存储地址的指针,那么我们如何访问 thead->next 呢?

什么时候指向结构的指针为NULL?

谢谢

【问题讨论】:

  • 刚刚添加了整个代码
  • 尝试自己回答以下问题。 thead==NULL 条件在此范围内意味着什么? thead-&gt;next==NULL 条件在此范围内意味着什么?
  • 如果 thread 等于 NULL,则 thread->next = temp 尝试取消引用 NULL 指针。
  • @AbhishekBansal 你提到的条件在这个算法中可能吗?
  • 如果代码使用while(thead != NULL) { ... },那么在循环之后,应该将什么设置为temp?需要设置为temp 的是一些.next 成员,但是什么指针?

标签: c pointers linked-list


【解决方案1】:

既然我已经真正理解了......对于那些仍然被困的人,我正在写这个......

当我使用 (thead!=NULL) 时,thead 指针实际上指向列表中的每个元素。当它到达最后一个元素时,它仍然遍历到下一个为 NULL 的元素,这与 (thead->next! =NULL) 在链表的最后一个元素处停止。

在打印的情况下,我们需要打印列表中的所有值,所以我们使用 while(thead!=NULL) 因为我们也需要打印最后一个元素。对于遍历,我们只需让指针指向最后一个元素节点,这样我们就可以在它处停下来,直到我们到达 NULL 指针才遍历。

我们无法取消对 NULL 的引用,因此出现了错误。

【讨论】:

    【解决方案2】:

    使用print(),代码不需要记住循环后的最后一个节点地址

    temp=head;
    while(temp!=NULL) {
        printf("%d",temp->data);
        temp=temp->next;
    }
    // temp == NULL at this point and code does not care what the last node was.
    

    使用insert(),代码确实需要记住循环后的最后一个节点地址。

    // First handle special case where the head of the list is NULL
    // otherwise ....
    while(thead->next!=NULL) {
        thead = thead->next;  
    }
    // temp->next == NULL at this point
    // Code can use `thead` to access the last node's members.
    thead->next = temp;
    

    头节点是第一个包含数据和地址的节点,还是只存储上图中的地址?

    struct node *head 是一个指针。当head != NULL时,它指向包含数据的第一个节点和一个next指针。

    如果头节点只是一个存储地址的指针,那么我们如何访问 thead->next ?

    thead 被初始化为head。通过取消引用thead,代码可以访问该节点的成员,包括.next

    什么时候指向结构的指针是NULL?

    问题不清楚。指向struct 的指针在其值等于NULL 时为NULL。这通常作为链表代码的结尾。

    【讨论】:

    • 你能回答最后 3 个问题,让我更清楚吗?
    • @Shaurya 为什么你编码struct node *temp=(struct node *)malloc(sizeof(struct node)); 而不是更简单的struct node *temp=malloc(sizeof(struct node)); 甚至更好的struct node *temp = malloc(sizeof *temp);?最后一个是首选。
    • malloc 返回一个 void 指针,表示内存已分配但与任何数据类型无关。所以实际上我在这里对用户生成的数据类型进行类型转换,即 (struct node*)。
    • @Shaurya C 不需要演员表来工作 - 这是不必要的。如果WET,则使用struct node *temp=(struct node *)malloc(sizeof(struct node));。如果DRY,则使用struct node *temp = malloc(sizeof *temp);
    • [错误] 从 'void*' 到 'node*' 的无效转换 [-fpermissive] 实施你的建议会在 dev c++ 中出现此错误。
    猜你喜欢
    • 1970-01-01
    • 2021-10-01
    • 2023-04-01
    • 1970-01-01
    • 2012-12-09
    • 1970-01-01
    • 2015-06-02
    • 1970-01-01
    • 2023-03-05
    相关资源
    最近更新 更多