【数据结构】双向链表中删除节点的方法实现(代码+详解)

【数据结构】双向链表中删除节点方法的实现(代码+详解)

分析

💕 在双向链表中,删除一个结点可能出现以下几种情况,取决于待删除的结点在链表中的位置:

  1. 删除头结点:

    • 如果待删除的结点是头结点,需要特殊处理,更新头结点为原头结点的后继结点,并释放原头结点的内存。
  2. 删除尾结点:

    • 如果待删除的结点是尾结点,需要特殊处理,更新尾结点为原尾结点的前驱结点,并释放原尾结点的内存。
  3. 删除中间结点:

    • 如果待删除的结点位于链表的中间位置,只需调整前驱结点和后继结点的指针,将它们连接在一起,并释放待删除结点的内存。

💕 这些情况可以进一步细分为以下几类:

  • 删除头结点

    • 头结点是唯一结点
    • 头结点后还有其他结点
  • 删除尾结点

    • 尾结点是唯一结点
    • 尾结点前还有其他结点
  • 删除中间结点


代码

c 复制代码
#include <stdio.h>
#include <stdlib.h>

// 定义双向链表的结点结构
typedef struct Node {
    int data;
    struct Node* prev;  // 前驱指针
    struct Node* next;  // 后继指针
} Node;

// 删除双向链表的头结点
Node* deleteHead(Node* head) {
    if (head == NULL) {
        printf("Error: Empty list\n");
        return NULL;
    }

    Node* newHead = head->next;

    if (newHead != NULL) {
        newHead->prev = NULL;
    }

    free(head);

    printf("Head node deleted successfully.\n");

    return newHead;
}

// 删除双向链表的尾结点
Node* deleteTail(Node* head) {
    if (head == NULL) {
        printf("Error: Empty list\n");
        return NULL;
    }

    if (head->next == NULL) {
        free(head);
        printf("Tail node (and the only node) deleted successfully.\n");
        return NULL;
    }

    Node* current = head;
    while (current->next->next != NULL) {
        current = current->next;
    }

    free(current->next);
    current->next = NULL;

    printf("Tail node deleted successfully.\n");

    return head;
}

// 删除双向链表的中间结点
Node* deleteMiddle(Node* head, int target) {
    if (head == NULL) {
        printf("Error: Empty list\n");
        return NULL;
    }

    Node* current = head;

    while (current != NULL && current->data != target) {
        current = current->next;
    }

    if (current == NULL) {
        printf("Error: Node with data %d not found in the list\n", target);
        return head;
    }

    if (current->prev != NULL) {
        current->prev->next = current->next;
    }

    if (current->next != NULL) {
        current->next->prev = current->prev;
    }

    free(current);

    printf("Node with data %d deleted successfully.\n", target);

    return head;
}

// 打印双向链表的内容
void printList(Node* head) {
    Node* current = head;

    while (current != NULL) {
        printf("%d ", current->data);
        current = current->next;
    }

    printf("\n");
}

int main() {
    // 创建一个简单的双向链表:1 <-> 2 <-> 3 <-> 4
    Node* head = (Node*)malloc(sizeof(Node));
    head->data = 1;
    head->prev = NULL;
    head->next = (Node*)malloc(sizeof(Node));
    head->next->data = 2;
    head->next->prev = head;
    head->next->next = (Node*)malloc(sizeof(Node));
    head->next->next->data = 3;
    head->next->next->prev = head->next;
    head->next->next->next = (Node*)malloc(sizeof(Node));
    head->next->next->next->data = 4;
    head->next->next->next->prev = head->next->next;
    head->next->next->next->next = NULL;

    printf("Original list: ");
    printList(head);

    // 删除头结点
    head = deleteHead(head);
    printf("List after deleting head: ");
    printList(head);

    // 删除尾结点
    head = deleteTail(head);
    printf("List after deleting tail: ");
    printList(head);

    // 删除中间结点(例如,删除值为3的结点)
    head = deleteMiddle(head, 3);
    printf("List after deleting middle node: ");
    printList(head);

    return 0;
}
相关推荐
是有头发的程序猿20 分钟前
用Open Claw接口做1688选品、价格监控、货源对比
开发语言·c++·人工智能
逆境不可逃38 分钟前
LeetCode 热题 100 之 543. 二叉树的直径 102. 二叉树的层序遍历 108. 将有序数组转换为二叉搜索树 98. 验证二叉搜索树
算法·leetcode·职场和发展
斯班奇的好朋友阿法法38 分钟前
离线ollama导入Qwen3.5-9B.Q8_0.gguf模型
开发语言·前端·javascript
计算机安禾40 分钟前
【数据结构与算法】第19篇:树与二叉树的基础概念
c语言·开发语言·数据结构·c++·算法·visual studio code·visual studio
副露のmagic1 小时前
哈希章节 leetcode 思路&实现
算法·leetcode·哈希算法
csuzhucong1 小时前
puzzle(1037)黑白、黑白棋局
算法
XiYang-DING1 小时前
【LeetCode】链表 + 快慢指针找中间 | 2095. 删除链表的中间节点
算法·leetcode·链表
Zarek枫煜1 小时前
[特殊字符] C3语言:传承C之高效,突破C之局限
c语言·开发语言·c++·单片机·嵌入式硬件·物联网·算法
寻寻觅觅☆1 小时前
东华OJ-基础题-30-求最晚和最早日期(C++)
数据结构·c++·算法
是Smoky呢2 小时前
springAI+向量数据库+RAG入门案例
java·开发语言·ai编程