📅  最后修改于: 2023-12-03 15:07:14.726000             🧑  作者: Mango
双向链表是一种常用的数据结构,它具有遍历方便、插入删除操作灵活等优点。然而,在使用双向链表时,有时需要进行节点的删除操作。本文将介绍如何在 C 语言中实现删除双向链表中节点的操作。
在 C 语言中,我们可以使用结构体来表示双向链表中的节点。这种结构体通常包括三个成员变量:前驱指针、后继指针和数据。
struct ListNode {
struct ListNode* prev; // 前驱指针
struct ListNode* next; // 后继指针
int data; // 数据
};
我们使用一个指向链表头部节点的指针 head 来表示整个双向链表。如果链表为空,则 head 指针为 NULL。
删除双向链表中的节点分为两种情况:
如果需要删除头部节点,则只需要将头部节点的后继节点作为新的头部即可。具体操作如下:
void delete_head(struct ListNode** head) {
if (*head != NULL) { // 判断链表是否为空
struct ListNode* tmp = *head; // 保存头部节点
*head = (*head)->next; // 将第二个节点作为新的头部
if (*head != NULL) {
(*head)->prev = NULL; // 如果新的头部不为空,则将其前驱指针设为空
}
free(tmp); // 释放原头部节点的内存
}
}
如果需要删除非头部节点,则需要找到待删除节点的前驱节点和后继节点,然后将两个节点连接。具体操作如下:
void delete_node(struct ListNode** head, struct ListNode* node) {
if (node == NULL || *head == NULL) { // 判断链表是否为空
return;
}
if (node == *head) { // 如果待删除节点为头部节点,则调用删除头部节点的函数
delete_head(head);
} else {
node->prev->next = node->next; // 将前驱节点的后继指针指向待删除节点的后继节点
if (node->next != NULL) {
node->next->prev = node->prev; // 如果待删除节点不为尾部节点,则将后继节点的前驱指针指向待删除节点的前驱节点
}
free(node); // 释放待删除节点的内存
}
}
双向链表中的节点删除操作相对复杂,需要考虑头部节点和非头部节点两种情况。使用指针操作时,需要特别注意指针为 NULL 的情况,以避免程序出错。本文给出的 C 程序中,可以通过函数调用的方式来实现删除双向链表中的节点的操作,使用方便且安全可靠。