这个程序应该删除单链表中的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 t : %dn", 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("errorn");
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("nnbeforen");
printlist(head);
deletenode(head,N);
printf("nnaftern");
printlist(head);
}
我使用current
作为临时指针,因为在第二个节点上的头部移动后,我需要指向旧头部的指针并使用 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
(struct node *
(和prev_node->next
(struct 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;
}