C语言 不使用函数的单向链表创建问题


//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

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

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

理想情况下,您应该使用临时指针,将其与链表的头部指针对齐,然后获取输入,分配并移动它,并继续仅使用它构建链表。链表的头部指针(此处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;
}

最新更新