侧边栏壁纸
博主头像
曾高明要发光

千里之行、始于足下

  • 累计撰写 12 篇文章
  • 累计创建 0 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

删除单链表中的最小值节点

曾高明要发光
2025-02-14 / 0 评论 / 0 点赞 / 49 阅读 / 2,078 字

要从单向链表中删除最小值节点,我们需要完成以下几个步骤:

找到最小值节点

记录其前驱节点(为了删除时能连接前后节点)

执行删除操作

处理特殊情况(如头节点是最小值的情况)

实现方法
C语言实现

#include <stdlib.h>

typedef struct Node {
    int data;
    struct Node* next;
} Node;

// 创建新节点
Node* createNode(int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    if (!newNode) {
        printf("内存分配失败\n");
        exit(1);
    }
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}

// 删除链表中的最小值节点
void deleteMinNode(Node** headRef) {
    if (*headRef == NULL) {
        printf("链表为空\n");
        return;
    }

    Node* current = *headRef;
    Node* prev = NULL;
    Node* minNode = *headRef;
    Node* prevMin = NULL;

    // 遍历链表寻找最小值节点及其前驱
    while (current != NULL) {
        if (current->data < minNode->data) {
            minNode = current;
            prevMin = prev;
        }
        prev = current;
        current = current->next;
    }

    // 删除最小值节点
    if (prevMin == NULL) {
        // 最小值是头节点
        *headRef = minNode->next;
    } else {
        // 最小值不是头节点
        prevMin->next = minNode->next;
    }

    free(minNode);
}

// 打印链表
void printList(Node* head) {
    Node* current = head;
    while (current != NULL) {
        printf("%d -> ", current->data);
        current = current->next;
    }
    printf("NULL\n");
}

int main() {
    Node* head = createNode(5);
    head->next = createNode(2);
    head->next->next = createNode(8);
    head->next->next->next = createNode(1);
    head->next->next->next->next = createNode(3);

    printf("原始链表: ");
    printList(head);

    deleteMinNode(&head);

    printf("删除最小值后: ");
    printList(head);

    // 释放链表内存
    while (head != NULL) {
        Node* temp = head;
        head = head->next;
        free(temp);
    }

    return 0;
}

算法分析
时间复杂度:O(n),需要遍历整个链表一次来找到最小值

空间复杂度:O(1),只使用了固定数量的指针变量

特殊情况处理
空链表:直接返回,不执行任何操作

多个最小值:此代码会删除第一个遇到的最小值节点

头节点是最小值:需要特殊处理以更新头指针

扩展:删除所有最小值节点
如果需要删除所有最小值节点(当有多个相同的最小值时),可以稍作修改:

    if (*headRef == NULL) return;

    // 首先找到最小值
    int minVal = (*headRef)->data;
    Node* current = (*headRef)->next;
    while (current != NULL) {
        if (current->data < minVal) {
            minVal = current->data;
        }
        current = current->next;
    }

    // 删除所有值为minVal的节点
    Node* dummy = createNode(0); // 哑节点简化操作
    dummy->next = *headRef;
    Node* prev = dummy;
    current = *headRef;

    while (current != NULL) {
        if (current->data == minVal) {
            prev->next = current->next;
            free(current);
            current = prev->next;
        } else {
            prev = current;
            current = current->next;
        }
    }

    *headRef = dummy->next;
    free(dummy);
}

这种方法使用哑节点(dummy node)简化了边界条件的处理,特别是当头节点需要被删除时。

0

评论区