简体   繁体   English

删除链接列表中的节点

[英]Deleting Nodes in a Linked List

After a lot of effort, I've managed to piece together a function that deletes some node from my linked list. 经过大量的努力,我已经设法将一个从我的链表中删除某个节点的函数拼凑在一起。 But, out of sheer interest, I would like to find out how you can go about deleting the first node from the list, ie the head. 但是,出于纯粹的兴趣,我想知道如何从列表中删除第一个节点,即头部。

My program asks for a letter to delete, so for example. 我的程序要求删除一封信,例如。 Hello is stored in the list, the user inputs H for deletion, so that now the list is ello At the moment with my code, the program crashes obviously as if H is deleted, there is no head, and the program doesn't know where to go to look for the list. Hello存储在列表中,用户输入H进行删除,所以现在列表是ello目前我的代码,程序崩溃,好像H被删除,没有头,程序不知道去哪里寻找清单。

Below is my current implementation, any clues or hints on how to modify this code( I would like to keep it similar to how I have) to allow Head Node Deletion would be much appreciated!. 下面是我目前的实现,关于如何修改此代码的任何线索或提示(我希望保持类似于我的方式)允许头节点删除将非常感谢!

EDIT: In response to below 编辑:回应下面

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;
}

The way it is now, inside DeleteNode , when you change the argument, it only changes the local variable, not the one outside the function. 现在的方式,在DeleteNode ,当您更改参数时,它只更改局部变量,而不是函数外部的变量。

You either have to pass the FullList to DeleteNode by pointer so that modifications done to it will be visible to the caller, or modify a local one and return it, and the caller must assign the returned FullList to its list. 你要么必须将传递FullListDeleteNode通过指针,以便完成它的修改将是可见的来电,或修改本地一个并返回,调用者必须将返回FullList其名单。

Either way, the changes made by DeleteNode must become visible to the caller. 无论哪种方式, DeleteNode所做的DeleteNode必须对调用者可见。

You can't do it without changing your existing code. 如果不更改现有代码,则无法执行此操作。

You're passing your FullList struct to your DeleteNode() function. 您正在将FullList结构传递给DeleteNode()函数。 This means that any changes to that struct are not visible back in main - the function is getting a copy of it. 这意味着对该结构的任何更改都不会在main - 该函数正在获取它的副本

You would need to change DeleteNode() to accept a pointer: 您需要更改DeleteNode()以接受指针:

void DeleteNode(FullList *temp, char c)

Then when calling it main() you would do: 然后在调用main()你会这样做:

DeleteNode(&List, s);

By doing this, you can change the value of temp->head in your function and it will be visible back in main() 通过这样做,您可以在函数中更改temp->head的值,它将在main()

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

Edit: The logic you'll need is: 编辑:您需要的逻辑是:

  • Check to see if temp->head->c == c 检查temp->head->c == c
  • If yes, replace temp->head with temp->head->next 如果是,请将temp->head替换为temp->head->next
  • else assign temp->head to a temp pointer *previous . 否则将temp->head指定给临时指针*previous Assign temp->head->next to a pointer *current . 在指针*current temp->head->next指定temp->head->next Loop through the list, moving both pointers. 循环遍历列表,移动两个指针。 When you find a match in current->c , assign current->next to previous->next and free() the current node. 当您在current->c找到匹配项时,请在current->c current->next previous->nextfree()分配current节点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM