📜  删除双向链表中节点的 C 程序

📅  最后修改于: 2022-05-13 01:57:39.382000             🧑  作者: Mango

删除双向链表中节点的 C 程序

先决条件:双向链接列表集 1|介绍和插入

编写一个函数来删除双向链表中的给定节点。
原始双向链表

方法:删除双向链表中的一个节点可以分为三大类:

  • 头节点删除后。

  • 删除中间节点后。

  • 删除最后一个节点后。

如果要删除的节点的指针和头指针已知,则所有提到的三种情况都可以分两步处理。

  1. 如果要删除的节点是头节点,则将下一个节点作为头节点。
  2. 如果一个节点被删除,连接被删除节点的下一个和上一个节点。

算法

  • 设要删除的节点为del
  • 如果要删除的节点是头节点,则将头指针更改为下一个当前头。
if headnode == del then
      headnode =  del.nextNode
  • 如果之前的del存在,则将next of previous 设置为del
if del.nextNode != none 
      del.nextNode.previousNode = del.previousNode 
  • 如果存在del的 next ,则将 next 的prev设置为del
if del.previousNode != none 
      del.previousNode.nextNode = del.next
C
// C program to implement
// the above approach
#include 
#include 
  
// A node of the doubly linked list 
struct Node 
{
    int data;
    struct Node* next;
    struct Node* prev;
};
  
/* Function to delete a node in a Doubly 
   Linked List. head_ref --> pointer to 
   head node pointer. del  -->  pointer 
   to node to be deleted. */
void deleteNode(struct Node** head_ref, 
                struct Node* del)
{
    // Base case 
    if (*head_ref == NULL || del == NULL)
        return;
  
    // If node to be deleted is head node 
    if (*head_ref == del)
        *head_ref = del->next;
  
    /* Change next only if node to be deleted 
       is NOT the last node */
    if (del->next != NULL)
        del->next->prev = del->prev;
  
    /* Change prev only if node to be deleted 
       is NOT the first node */
    if (del->prev != NULL)
        del->prev->next = del->next;
  
    // Finally, free the memory occupied by del
    free(del);
    return;
}
  
// UTILITY FUNCTIONS 
/* Function to insert a node at the 
   beginning of the Doubly Linked List */
void push(struct Node** head_ref, 
          int new_data)
{
    // Allocate node 
    struct Node* new_node = 
           (struct Node*)malloc(sizeof(struct Node));
  
    // Put in the data  
    new_node->data = new_data;
  
    /* Since we are adding at the beginning,
       prev is always NULL */
    new_node->prev = NULL;
  
    // Link the old list off the new node 
    new_node->next = (*head_ref);
  
    // Change prev of head node to new node 
    if ((*head_ref) != NULL)
        (*head_ref)->prev = new_node;
  
    // Move the head to point to the new node 
    (*head_ref) = new_node;
}
  
/* Function to print nodes in a given doubly 
   linked list. This function is same as 
   printList() of singly linked list */
void printList(struct Node* node)
{
    while (node != NULL) 
    {
        printf("%d ", node->data);
        node = node->next;
    }
}
  
// Driver code
int main()
{
    // Start with the empty list 
    struct Node* head = NULL;
  
    /* Let us create the doubly 
       linked list 10<->8<->4<->2 */
    push(&head, 2);
    push(&head, 4);
    push(&head, 8);
    push(&head, 10);
  
    printf(
    "Original Linked list ");
    printList(head);
  
    /* Delete nodes from the doubly 
       linked list */
    // Delete first node
    deleteNode(&head, head); 
  
    // Delete middle node
    deleteNode(&head, head->next); 
  
    // Delete last node
    deleteNode(&head, head->next); 
  
    /* Modified linked list will be 
       NULL<-8->NULL */
    printf(
    "Modified Linked list ");
    printList(head);
  
    getchar();
}


输出:

Original Linked list 10 8 4 2 
Modified Linked list 8

复杂性分析:

  • 时间复杂度: O(1)。
    由于不需要遍历链表,因此时间复杂度是恒定的。
  • 空间复杂度: O(1)。
    由于不需要额外的空间,因此空间复杂度是恒定的。

有关详细信息,请参阅有关删除双向链表中的节点的完整文章!