在c开头添加节点

时间:2013-01-20 09:28:45

标签: c linked-list

这是我在开始时添加节点的代码。

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");
}

4 个答案:

答案 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);
  }
}

如果将指针传递给某个函数,它可以更改某些内容,但不能更改指针本身。因此,自然的结论是使某些东西本身成为指针 - 即指向指针的指针。

原则上你可以把这个指针链接到你想要的深度,但实际上你通常不需要任何东西,而是“指向指向事物的指针”。

其他几点。尽量避免使用lll之类的变量名,因为小写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();
  1. 如果我通过stdin发送“abcd {enter}”,那将是什么?
  2. 如果我通过stdin发送“abcd {enter}”,那会是什么?
  3. 如果我通过stdin发送EOF信号,scanf会返回什么?
  4. 如果成功读取并将值放入两个变量x和y中,那么z将是哪个值?