这是我在开始时添加节点的代码。
void screate(ll *node)
{
ll *newNode=(ll *)malloc(sizeof(ll));
printf("Enter number :\t");
scanf("%d",&newNode->data);
if(newNode->data != NULL)
{
newNode->next=node;
node= newNode;
screate(node);
}
else
{
free(newNode);
newNode=NULL;
}
}
即使我发现相同的代码here,我也无法弄清楚,为什么我输错了。
这是当前节点
56->78->77->NULL
但是,当我试图在开头添加新节点时,我仍然得到相同的输出,即 56->78->77->NULL
。需要帮助!!
更新
void show(ll *node){
while(node->next != NULL)
{
printf("%d->",node->data);
node=node->next;
}
printf("NULL");
}
答案 0 :(得分:4)
您正在分配node
,这只是该功能的参数。由于它是按值传递的,因此不会更新调用函数所持有的版本。
您需要将指针传递给它(即ll **node
)并更改您的代码以分配给*node
,并更改调用者以在参数之前添加&
拿它的地址。
void screate(ll **node)
{
ll *newNode=malloc(sizeof(ll));
printf("Enter number :\t");
scanf("%d",&newNode->data);
if(newNode->data != NULL)
{
newNode->next=*node;
*node= newNode;
screate(node);
}
else
{
free(newNode);
}
}
如果将指针传递给某个函数,它可以更改某些内容,但不能更改指针本身。因此,自然的结论是使某些东西本身成为指针 - 即指向指针的指针。
原则上你可以把这个指针链接到你想要的深度,但实际上你通常不需要任何东西,而是“指向指向事物的指针”。
其他几点。尽量避免使用l
和ll
之类的变量名,因为小写L's很容易与许多字体中的数字1(和大写字母I)混淆。此外,您再次使用screate()
的递归调用可能会更有效地作为while
循环。有些编译器会发现它是tail-recursive并且无论如何都要优化到一个循环,但是当我首先使用循环时,我从不喜欢依赖于那种东西。
答案 1 :(得分:3)
newNode->next=node; node = newNode;
问题是node = newNode
只更改node
的本地副本,这意味着调用者看不到更改。对于调用者而言,就好像你从未调用过该函数一样,node
仍然指向它之前所指向的位置。
您可能希望传递ll **node
并更改*node
或其他内容。
答案 2 :(得分:1)
您应该使用参数更改签名作为指向链接列表指针的指针
void screate(ll **node);
你的函数中相应的指针变化必须像这样
newNode->next=*node;
*node= newNode;
screate(&node);
答案 3 :(得分:0)
我建议更改你的screate函数,使其返回struct ll *
。返回值将对应于您的新头节点。
if(newNode->data != NULL)
不是检测scanf输入失败的明智方法。事实上,那段代码并不合理,期间。 NULL被标识为空指针集的成员。 newNode-> data是一个int,而不是一个指针。将其与0进行比较会更有意义。 [此处] [1]是标准化的scanf参考。仔细阅读并回答以下问题,您将了解如何区分scanf的成功与否:
int x, y;
int z = scanf("%d%d", &x, &y);
int c = getchar();