[英]Linklist insertion of node displays nothing
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
void insert( struct node *q,int num)
{
struct node *temp;
if( q == NULL)
{
q = (struct node*)malloc(sizeof(struct node));
q->data = num;
q->next = NULL;
}
else
{
temp = q;
while( temp != NULL)
{
temp = temp->next;
}
temp = (struct node*)malloc(sizeof(struct node));
temp->data = num;
temp->next = NULL;
}
}
void display(struct node *q)
{
struct node *temp;
temp = q;
while(temp != NULL)
{
printf("%d",temp->data);
temp = temp->next;
}
}
int main()
{
struct node *a;
a = NULL;
insert( a,13);
insert( a,13);
display(a);
return 0;
}
在insert
函数q
是指向初始化为NULL的struct节点的指针。
在这里,我看到第一个q是否为NULL。 如果它为null,那么我正在分配堆内存,数据和下一个指针,这样q现在是一个正在引用第一个数据的指针。 如果q不为NULL,则我使用一个temp指针,该指针指向q所指向的结构节点,因此直到temp变为NULL时,temp转到temp-> next,然后它分配堆内存,将数据和下一个指针放入空值。
但是它没有显示任何显示功能,请对此进行纠正,以及如何在链接列表中使用堆栈和堆内存。
回想一下,C语言中的参数是传递值 ,包括指针参数。
当q == NULL
,您正在分配内存并将内存分配给q
,但这不会在函数外更改q
:仅会更改函数内 q
的副本。
为了更改参数q
指向的内容 ,并使这些更改反映在函数外部,您需要将指针传递给指针,例如:
void insert(struct node **q, int num)
并更改您使用q
,例如
if (*q == NULL)
*q = (struct node *) malloc(sizeof(struct node));
此外,在其他情况下,应循环运行直到temp->next == NULL
,然后使用以下命令添加新节点:
temp->next = (struct node*) malloc(sizeof(struct node));
更改
insert( struct node *q,int num)
insert( struct node **q,int num)
在main()
,更改
insert( a,13)
至insert( &a,13)
您需要修改实际参数而不是形式参数,因此请使用按地址 传递而不按值传递 ,
意味着,在insert()
内部,当您将值赋给q
它并没有反映到a
,因为您只是传递a的值,以便使更改反映到传递a的地址。
也,
另一个问题是在insert()
的else
块内
将while( temp != NULL)
更改为while( temp->next != NULL)
您必须在insert()
函数中使用指向指针的指针,因为您使用malloc()
分配了新内存,但是指针仍将指向NULL。 因此,要修改指针本身,如果使用参数,则必须使用指向指针的指针。 恕我直言,如果返回指针会更好。
您需要返回在插入中分配的指针。
总的来说,a是指向NULL的指针。 第一次插入后,a仍然是指向NULL的指针,因为q具有指针,而不是a。
a的值是您可以找到结构节点的地址。 q是a值的副本,NULL也是如此。 当您使用malloc()时,它会为q分配一个值,这是结构节点的地址, 但不会改变a!
要么:
/* a has a value and it doesn't malloc q */ main() { struct node a = {0}; insert(&a, 13); }
要么
/* you return the value of q (address of struct node) and assign it to a */ struct node *insert(struct node *q, int num) { blah blah return q; } main() { struct node *a = NULL; a = insert(a, 13); }
要么
/* I'm finding this hard to explain because of 2 redirections */ void insert( struct node **q, int num ) { if ( *q == NULL ) { *q = malloc() etc etc } } main() { struct node *a = NULL; insert(&a, 13); }
但是在插入的后半部分,您也会犯类似的错误。 您需要分配内存并将其分配给下一个,而不是相反。
看来问题在于您要遍历列表的末尾。 因此,当温度变为空时,您说,嘿,我找到了终点。 然后创建一个新节点。 但是,您永远不要将前一个节点指向新节点。
我会改变这一点:
while( temp != NULL)
对此:
while( temp->next != NULL)
因此,到达终点时,您仍然可以参考列表。 然后,您将需要相应地更改其余逻辑,但是至少有可能。
就像其他人所说的那样,您的功能也不适用于初始节点。 我会考虑有一个单独的函数来初始化一个空列表。 但这主要是样式选择。
替换您的代码:
while( temp != NULL)
{
temp = temp->next;
}
temp = (struct node*)malloc(sizeof(struct node));
temp->data = num;
temp->next = NULL;
通过
while( temp->next != NULL)
{
temp = temp->next;
}
temp->next = (struct node*)malloc(sizeof(struct node));
temp->next->data = num;
temp->next->next = NULL;
这是您程序的固定版本。 问题是,指针是按值复制到功能,所以当你的函数退出,传入的指针a
在这种情况下,没有被分配到任何东西。 您要做的唯一一件事就是通过分配一些内存而不是free
内存来泄漏内存。
解决方案是按引用传递指针,并在C中使用指针到指针完成传递。
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
void insert( struct node **q,int num)
{
struct node *temp;
if( *q == NULL)
{
*q = (struct node*)malloc(sizeof(struct node));
(*q)->data = num;
(*q)->next = NULL;
}
else
{
temp = *q;
while( temp != NULL)
{
temp = temp->next;
}
temp = (struct node*)malloc(sizeof(struct node));
temp->data = num;
temp->next = NULL;
}
}
void display( struct node *q)
{
struct node *temp;
temp = q;
while(temp != NULL)
{
printf("%d",temp->data);
temp = temp->next;
}
}
int main()
{
struct node *a;
a = NULL;
insert( &a,13);
insert( &a,13);
display(a);
free(a->next); //de-alloc memory
free(a);
return 0;
}
您可以通过两种方式解决此问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.