【问题标题】:Singly Linked List creation problem without using a function不使用函数的单链表创建问题
【发布时间】:2020-05-25 10:27:54
【问题描述】:
//linked_list_1

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

struct list
{
    int data;
    struct list *link;
};

int main()
{
    struct list *ll=NULL, *tp=NULL;
    int n=3, i;

    ll=(struct list *)malloc(sizeof(struct list));

    scanf("%d",&ll->data);

    for(i=1; i<n; i++)
    {
        tp=(struct list *)malloc(sizeof(struct list));
        scanf("%d",&tp->data);
        ll->link=tp;
        ll=ll->link;
    }

    ll->link=NULL;

    while(ll)
    {
        printf("\n%d",ll->data);
        ll=ll->link;
    }
}
//linked_list_2

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

struct list
{
    int data;
    struct list *link;
};

void linked_list(struct list *,int);

int main()
{
    struct list *ll=NULL;
    int n=3;

    ll=(struct list *)malloc(sizeof(struct list));

    linked_list(ll,n);


    while(ll)
    {
        printf("\n%d",ll->data);
        ll=ll->link;
    }
}

void linked_list(struct list *kk, int n)
{
    struct list *tp=NULL;
    int i;
    scanf("%d",&kk->data);
    for(i=1; i<n; i++)
    {
        tp=(struct list *)malloc(sizeof(struct list));
        scanf("%d",&tp->data);
        kk->link=tp;
        kk=kk->link;
    }
    kk->link=NULL;
}

两个程序都一样,第二个程序是使用函数创建链表:void linked_list(struct list *kk, int n) 第一个程序也是创建链表,但没有任何函数。第二个程序运行正常,但第一个程序运行不正确。

如果两个程序的输入均为2 5 4,则第二个程序输出为2 5 4,但第一个程序输出仅为4

为什么第一个程序没有以正确的方式运行?是什么原因?

【问题讨论】:

    标签: c linked-list singly-linked-list


    【解决方案1】:

    第一个程序的问题是你在输入时移动了链表的头部。因此,当您完成输入后,链表的头部现在位于它的最后一个节点。然后,当您尝试打印出链表时,您将得到它的最后一个节点,因为当您接受最后一个输入时头部已移动到那里。

    理想情况下,您应该使用临时指针,将其与链表的头指针对齐,然后获取输入,分配并移动它,并继续仅使用它来构建链表。初始化后链表的头指针(这里是ll)不应该像这样移动:

    ll=ll->link; //Wrong!
    

    直到绝对需要这样做。这将导致链表被截断,并且您将丢失节点。

    理想情况下,您的代码应该是这样的:

    ll=(struct list *)malloc(sizeof(struct list));
    tp = ll; //Align the temporary pointer with the head of the linked list.
    scanf("%d",&tp->data);
    
    for(i=1; i<n; i++)
    {
        //Allocate memory to the link of the temporary pointer since it is also a type of struct list.
        tp->link=(struct list *)malloc(sizeof(struct list)); 
        scanf("%d",&tp->link->data);
        tp = tp->link; //Move only the temporary pointer.
    }
    
    tp->link=NULL; //Finally assign NULL when done taking inputs.
    

    请注意,我只是使用临时指针来做所有事情。

    第二个程序工作的原因是因为你将头指针的地址传递给你用来构建链表的函数。现在此函数获取kk 中地址的副本,该地址是链表的起始地址,并使用它在那里构建链表。但是在main() 中,ll 指针仍然保存着您最初分配内存的原始地址。因此,当您返回main() 打印链表时,构建链表后,您从链表的实际头部开始,仍然由ll 持有,您可以打印出整个链表。

    但这仍然存在我之前提到的相同缺陷。您在打印时移动了链表的头部(即ll)。

    while(ll)
    {
        printf("\n%d",ll->data);
        ll=ll->link; //This is wrong!
    }
    

    所以在你打印完链表之后,你的链表头现在是 NULL。所以如果你想在打印后对实际的链表做一些事情,现在是不可能的,因为你已经把 head 设为 NULL。所以同样的解决方案是使用一个临时指针将它与链表的头部对齐,然后用它来打印出链表。像这样的:

    struct list *tp = ll;
    while(tp)
    {
        printf("\n%d",tp->data);
        tp=tp->link;
    }
    

    【讨论】:

      猜你喜欢
      • 2019-07-23
      • 2020-09-29
      • 2013-11-06
      • 1970-01-01
      • 2015-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多