如何通过在末尾添加节点来创建链接列表?

时间:2016-08-13 18:57:43

标签: c linked-list

我编写了一个程序,询问用户是否要在链表中插入新节点(在末尾插入),然后打印整个链表。只要用户输入值0,程序就会停止并打印链接列表。

以下是代码:

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

struct ListNode
{
   int  data;
   struct   ListNode    *next;
};

int main()
{
    int     val,
            flag = 1;

struct  ListNode    *p,
                    *head,
                    *temp;

printf("press 0 to exit\n");

do
{
    printf("enter the data : ");
    scanf("%d", &val);

    p = (struct ListNode *)malloc(sizeof(struct ListNode));

    if(head == NULL)
    {
        p -> data = val;
        p -> next = NULL;
        head = p;
        temp = p;
    }
    else
    {
        p -> data = val;
        p -> next = NULL;
        temp -> next = p;
    }

    printf("continue?");
    scanf("%d", &flag);

 }while(flag != 0);

 temp = head;

 while(temp != NULL)
 {
    printf("%d -> ", temp -> data);
    temp = temp -> next;
 }
 printf("\n");

 return 0;
 }

现在我输出的问题是它只打印第一个和最后一个节点。其间的其他节点未打印。

以下是示例输出:

  

电话:12 13 14 15

     

输出:12 15

有人可以向我解释我哪里出错了吗?我总是可以将整个事情放在一个函数中并且执行它,但是现在我想在不使用函数调用的情况下尝试相同的事情。

3 个答案:

答案 0 :(得分:4)

在以下if-else块中,

 if(head == NULL)
    {
        p -> data = val;
        p -> next = NULL;
        head = p;
        temp = p;
    }
    else
    {
        p -> data = val;
        p -> next = NULL;
        temp -> next = p;
    }

最初,当head为NULL时,您将headtemp分配给p。所以,temp指向第一个元素。之后,每次获得新元素时,都会将temp->next重新分配给该新元素,而不会更新temp。实际上,您每次都要分配head->next。要更正此问题,您需要每次都更新temp

if(head == NULL)
    {
        p -> data = val;
        p -> next = NULL;
        head = p;
        temp = p;
    }
    else
    {
        p -> data = val;
        p -> next = NULL;
        temp -> next = p;
        temp = p;

    }

在声明head时,您还需要将其初始化为NULL,因为默认情况下不会对C中的局部变量进行初始化。

答案 1 :(得分:1)

存在以下问题:

  1. head未初始化,正如BLUEPIXY在评论中提到的那样。

    struct  ListNode    *p,
                        /* *head, */ // ISSUE: head not initialized
                        head = NULL,  
                        *temp;
    
  2. 添加其他节点时,您不会更新temp

     else
    {
        p->data = val;
        p->next = NULL;
        temp->next = p;
        temp = p;       // NEED to update temp
    }
    
  3. 此外,无需转换malloc

    的结果

    同时建议通过检查其返回值来检查malloc是否成功。就像,在这种情况下:

    p = malloc(sizeof(struct ListNode));
    if (p == NULL) {
        /* malloc failed. Code to handle the error */
    }
    

答案 2 :(得分:1)

只有当您创建了第一个节点时,才会在p中存储当前节点,即temp

您需要从

修改此代码段
if(head == NULL)
    {
        p -> data = val;
        p -> next = NULL;
        head = p;
        temp = p;
    }
    else
    {
        p -> data = val;
        p -> next = NULL;
        temp -> next = p;
    }

if(head == NULL)
    {
        p -> data = val;
        p -> next = NULL;
        head = p;
        temp = p;
    }
    else
    {
        p -> data = val;
        p -> next = NULL;
        temp -> next = p;
       temp=p;
    }

现在它可以正常工作。在p循环的每次迭代后,您需要将指针存储在temp中的当前节点while