【问题标题】:Recursive linked list in CC中的递归链表
【发布时间】:2017-03-22 18:42:45
【问题描述】:

我刚刚尝试在 C 中实现一个递归链表追加,出于某种原因,无论我做什么,我都会保持为 NULL,即使我在遇到 NULL 值时进行 malloc。

以下代码不打印任何内容。有什么想法吗?

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

typedef struct node {
  unsigned v;
  struct node* next;
} node;

void insert(unsigned x, node* l) {
  if (l == NULL){
    node* new_node = (node*)malloc(sizeof(node));
    new_node->v = x;
    new_node->next = NULL;
    l = new_node;
  }
  else {
    insert(x, l->next);
  }
}

void print(node *l) {
  if (l == NULL) return;
  printf("%d\n", l->v);
  print(l->next);
}

int main(){

  node* l = NULL;
  insert(1, l);
  insert(2, l);

  print(l);

  return 0;
}

非常感谢您的帮助。

编辑:即使我初始化它,它仍然是一样的。

【问题讨论】:

  • l 未初始化。
  • 你从来没有将l指向任何东西——如果它是空的,你(不)幸运,因为它是一个未初始化的指针。您还会遇到 insert() 函数的问题,该函数无法防止尝试重新插入已包含在列表中的节点。
  • l = new_node; 不会像您认为的那样做 - 您需要传入指向指针的指针作为参数 (node** l) 并分配 *l = new_node;
  • @UnholySheep 亲爱的上帝......谢谢你。我在这上面浪费了我生命中的 3 个小时。请问旧代码到底是什么问题..我仍然不明白为什么它不起作用。
  • node* l 作为参数意味着您的函数有一个本地指针变量,该变量指向与您传入的指针相同的地址。但是仅更改它指向的内容(通过l = new_node;)更改函数内的指针指向的内容,它不会影响您作为参数传递的指针。 - 这就是为什么你需要一个指向指针的指针

标签: c recursion linked-list


【解决方案1】:
#include <stdlib.h>
#include <stdio.h>

typedef struct node {
unsigned v;
struct node* next;
} node;

node* insert(unsigned x, node** ll) {
  if (*ll == NULL){
*ll = (node*)malloc(sizeof(node));
(*ll)->v = x;
(*ll)->next = NULL;

  }
  else {
    insert(x, &(*ll)->next);
}
}

void print(node *l) {if (l == NULL) return;
printf("%d\n", l->v);
print(l->next);
}

int main(){

node* l = NULL;
insert(1, &l);
insert(2, &l);
print(l);

return 0;
}

编译时没有 gcc 没有开关

输出: 1 2

【讨论】:

    【解决方案2】:

    首先,您将 l 按值传递给您的函数,因此您不会看到对其进行的任何更改。目前,当您将 l 设置为 new_node 时,您只需在方法 insert 中更改 l 的本地值。您可能希望修改您的函数以返回 l 并将您的 main 中的 l 设置为该函数的返回值。

    node *insert(int x, node *l){
      //.... your method
      return l;
    }
    

    主要:

    node *l = NULL;
    l = insert(1, l);
    l = insert(2, l);
    

    其次,出于同样的原因,您的递归调用不会将节点附加到您的 LL。将调用更改为:

     l->next = insert(x, l);
    

    【讨论】:

    • 谢谢,这个解决方案似乎也有效。我只是希望我的插入是 void 类型,而不是返回指针。在那种情况下,需要一个双指针,对吧?
    猜你喜欢
    • 1970-01-01
    • 2017-05-07
    • 1970-01-01
    • 1970-01-01
    • 2013-03-07
    • 1970-01-01
    • 1970-01-01
    • 2021-03-25
    相关资源
    最近更新 更多