在双向链表中删除一个指定的节点,可以分为下面的这3种情况:
(a) 原始的双向链表
(b) 删除头节点后
(c) 删除中间节点后
(d) 删除尾节点后
算法
假设需要被删除的节点称之为delNode.
1) 如果delNode为头节点,则将头指针指向后续的节点。
2) 如果delNode的前向节点存在,则将前向节点的后向指针置为delNode的后向指针。
3) 如果delNode的后向节点存在,则将后向节点的前向指针置为del的前向指针。
#include <iostream> struct Node { int data; Node *next; // 指向下一个节点 Node *prev; // 指向前一个节点 }; /* 实现双向链表中删除一个节点 head --> 链表的头部指针. delNode --> 需要被删除的节点 */ void deleteNode(Node **head, Node *delNode) { //是否为空链表 if (*head == NULL || delNode == NULL) return; //删除头节点 if (*head == delNode) *head = delNode->next; //被删节点不是尾节点 if (delNode->next != NULL) delNode->next->prev = delNode->prev; //被删节点不是首节点 if (delNode->prev != NULL) delNode->prev->next = delNode->next; delete delNode; return; } // 给定链表的头指针(head)以及一个整数,插入一个新的节点至链表的头部 // 之所以传入双指针,因为函数中需要修改链表 void push(Node** head, int newData) { //1. 分配新节点内存 Node* newNode = new Node; //2. 赋值 newNode->data = newData; //3. 将原始头节点做为新节点的后向指针,而前向指针置为NULL newNode->next = (*head); newNode->prev = NULL; //4. 将原始头节点的前向指针置为新的节点 if ((*head) != NULL) (*head)->prev = newNode; //5. 将头指针置为新的节点 (*head) = newNode; } void printList(Node *head) { while (head != NULL) { std::cout<<" "<<head->data<<" "; head = head->next; } std::cout << std::endl; } int main() { //初始化链表为:10<->8<->6<->4<->2<->0 Node* head = NULL; push(&head, 0); push(&head, 2); push(&head, 4); push(&head, 6); push(&head, 8); push(&head, 10); std::cout << "Original DLL is: "; printList(head); //删除首节点10 deleteNode(&head, head); //删除中间节点4 deleteNode(&head, head->next->next); //删除尾节点0 deleteNode(&head, head->next->next->next); std::cout << "New DLL is: "; printList(head); return 0; }
输出:
Original DLL is: 10 8 6 4 2 0
New DLL is: 8 6 2
时间复杂度: O(n)
时间: 2024-10-11 17:14:54