问题描述
此程序应删除单链表中的N节点。如果我把N=1或N=2,这是可以的,程序可以工作。但当N=0时,输出将打印具有随机值的无限个节点(在删除节点0之后)。我认为程序看不到新的负责人。感谢帮助!
#include <stdio.h>
#include <stdlib.h>
#define N 0
struct node {
int data;
struct node *next;
};
void printlist(struct node *head){
struct node *current=head;
int i=0;
while (current!=NULL){
printf("node number %d : %d
", i, current->data);
current=current->next;
i++;
}
}
int deletenode(struct node *head,int n){
struct node *current=head;
struct node *previous=head;
int i=0;
while(current!= NULL){
if (n==i && i!=0){
previous->next=current->next;
free(current);
return 1;
}
else if (n==i && i==0){
head=head->next;
free(current);
return 1;
}
i++;
previous=current;
current=current->next;
return 0;
}
printf("error
");
exit(EXIT_FAILURE);
}
void main(){
struct node *n1=malloc(sizeof(struct node));
struct node *n2=malloc(sizeof(struct node));
struct node *n3=malloc(sizeof(struct node));
struct node *head=n1;
n1->data=5;
n1->next=n2;
n2->data=10;
n2->next=n3;
n3->data=15;
n3->next=NULL;
printf("
before
");
printlist(head);
deletenode(head,N);
printf("
after
");
printlist(head);
}
我使用current
作为临时指针,因为在第二个节点上的Head移动之后,我需要一个指向旧Head的指针并使用Free。
推荐答案
C始终通过值传递,因此更改参数对调用方没有任何影响。
void foo(int i) {
i = 1234; // No effect on caller.
}
void foo(int *p) {
p = NULL; // No effect on caller.
}
如果要修改变量(如调用方的head
),则需要传递指向该变量的指针。(您仍然可以更改指针引用的值。)
int deletenode(struct node **head, int n) {
...
}
deletenode(&head, N);
现在,您可以简单地将代码中的每个head
实例替换为(*head)
,以说明新的调用约定,但这将浪费简化的机会。通过拥有指向struct node *
的指针,我们不需要不同地处理head
(astruct node *
)和prev_node->next
(astruct node *
)。
int delete_node_n(struct node **ptr, unsigned n) {
// Make `ptr` point to the pointer we want to modify.
// This will either be the `head` variable
// or the `next` field of some node.
while (1) {
if (!*ptr)
return 0;
if (!n)
break;
ptr = &( (*ptr)->next );
--n;
}
struct node *to_free = *ptr;
*ptr = (*ptr)->next;
free(to_free);
return 1;
}