我正在练习链表代码。下面是插入函数:
Node* insert_at_pos(Node *head, int pos){
struct Node *ptr=NULL;
printf("enter data\n");
ptr=(Node*) malloc(sizeof(Node));
scanf("%d",&ptr->data);
ptr->next=NULL;
if (pos==0){
if (head==NULL){
head=ptr;
return head; //return that I want to remove
}
}
printf("done\n");
}
如果我返回Node*
,我认为此代码仍然有效,而不是返回void
,因为我通过引用传递值。因此,head
的值应自动更新而不是返回它,但如果我删除Node*
并将void
放入insert_at_pos
的返回类型,则它不会起作用}。
而且,我正在调用insert_at_pos
这样的函数::
Node *head=insert_at_pos(head,0);
可能的解释是什么或这里出了什么问题?
答案 0 :(得分:2)
基本上有两种方法可以解决这个问题。您传递指针的地址(类型Node**
,传递&head
)或您创建单独的列表类型。
第二个解决方案看起来像这样:
typedef struct List {
Node *head;
} List;
然后可以创建一个新的空列表:
List *list = malloc(sizeof (List));
list->head = NULL;
两种方式都很好。从概念上讲,第二种解决方案更好地匹配实际问题,因为它区分了List和数据节点。您可以创建列表并添加或删除值,而无需更改列表句柄。
第一个解决方案尝试通过让列表头为列表句柄来跳过列表的单独实体。问题在于空列表没有任何节点,因此空列表用NULL表示。这意味着列表句柄在列表从空转换为非空或从非空转换为空时更改,因此当您插入或删除项时,列表句柄可能会更改。
使用第一个解决方案的插入函数可以这样声明:
void insert(Node **head, int value);
电话会是这样的:
Node *head = null;
insert(&head, 42);
或者它可以像这样声明(如你的问题):
Node* insert(Node *head, int value);
并且这样调用:
Node *head = null;
head = insert(head, 42);