删除链接列表中的节点

时间:2011-11-26 20:19:23

标签: c list linked-list

经过大量的努力,我设法将一个从我的链表中删除某个节点的功能拼凑在一起。但是,出于纯粹的兴趣,我想了解如何从列表中删除第一个节点,即头部。

我的程序要求删除一封信,例如。 Hello存储在列表中,用户输入H进行删除,现在列表为ello 目前使用我的代码,程序显然崩溃,好像H被删除,没有头,程序也不知道去哪里查找列表。

下面是我当前的实现,关于如何修改此代码的任何线索或提示(我希望保持类似于我的方式)允许头节点删除将非常感谢!。

编辑:回应以下

FullList DeleteNode(FullList temp, char c) {
FullList remember;
FullList ptr;
while (temp.head->c != c) {
    remember.head = temp.head;
    temp.head = temp.head->next;
}
ptr.head = temp.head->next;
free(temp.head);
remember.head->next = ptr.head;
return temp;
}

int main(void) {
FullList List;
char c, s;
List.head = NULL;

while ((c=getchar()) != '.') {
    List = addToEnd(List, c);
}
scanf(" %c", &s);
List = DeleteNode(List, s);
while (List.head != NULL) {
    printf("%c", List.head->c);
    List.head = List.head->next;
}
return 0;
}

typedef struct List {
 char c;
 struct List *next;
}List;

typedef struct {
 List *head;
 List *tail;
}FullList;

 List *insertList(char c, List *t1) {
  List *t = (List*)calloc(1, sizeof(List));
  t->c = c ;
  t->next = t1;
 return t;
 }

FullList addToEnd(FullList c, char element) {
 if (c.head == NULL) { 
    c.head = c.tail = insertList(element, NULL);
 }else {
    c.tail->next = insertList(element, NULL);
    c.tail = c.tail->next;
 }
 return c;
} 

void DeleteNode(FullList temp, char c) {
 FullList remember;
 FullList ptr;
 while (temp.head->c != c) {
    remember.head = temp.head;
    temp.head = temp.head->next;
 } 
 ptr.head = temp.head->next;
 free(temp.head);
 remember.head->next = ptr.head;
} 


int main(void) {
 FullList List;
 char c, s;
 List.head = NULL;

 while ((c=getchar()) != '.') {
    List = addToEnd(List, c);
 }
 scanf(" %c", &s);
 DeleteNode(List, s);
 while (List.head != NULL) {
    printf("%c", List.head->c);
    List.head = List.head->next;
 }
 return 0;
}

2 个答案:

答案 0 :(得分:1)

现在的方式,在DeleteNode内,当你改变参数时,它只改变局部变量,而不是函数外的变量。

您必须通过指针将FullList传递给DeleteNode,以便调用者可以看到对其进行的修改,或者修改本地修改并将其返回,并且调用者必须分配将FullList返回到其列表中。

无论哪种方式,DeleteNode所做的更改都必须对来电者可见。

答案 1 :(得分:1)

如果不更改现有代码,则无法执行此操作。

您正在将FullList结构传递给DeleteNode()函数。这意味着对该结构的任何更改都不会在main中显示 - 该函数正在获取它的副本

您需要更改DeleteNode()以接受指针:

void DeleteNode(FullList *temp, char c)

然后在调用main()时,你会这样做:

DeleteNode(&List, s);

通过执行此操作,您可以更改函数中temp->head的值,它将显示在main()

temp->head = temp->head->next;

编辑:您需要的逻辑是:

  • 检查是否temp->head->c == c
  • 如果是,请将temp->head替换为temp->head->next
  • 否则将temp->head分配给临时指针*previous。将temp->head->next分配给指针*current。循环遍历列表,移动两个指针。当您在current->c中找到匹配项时,请将current->next分配给previous->nextfree() current节点。