13:在O(1)时间删除单链表节点

单向链表O(1)时间删除节点
本文介绍了一种在O(1)时间内删除单向链表中指定节点的方法,通过让待删节点复制其下一个节点的值并删除下一节点来实现,适用于非尾节点的情况;对于尾节点,则采用常规方法。文章提供了具体实现代码。

题目:给定单项链表的头指针和一个节点指针,定义一个函数在O(1)时间删除该节点。


解析:
删除单向链表中的一个节点,常规做法是必须找到待删除节点的前一个节点才能实现,而这样做的时间复杂度是O(n),无法满足要求。
创新想法:当我们想删除一个节点时,并不一定要删除节点本身,可以用当前节点保存它下一节点的值,然后删除它的下一个节点。

情况案例:
1. 输入节点为NULL
2. 单链表只有一个节点,即删除头节点
3. 待删除节点是尾节点,即没有下一节点
4. 待删除不是尾节点

当待删除节点是尾节点时,采用常规方法:须找到待删除节点的前一个节点才能实现O(n),但对于其他的非尾节点可以以O(1)的时间删除,因此平均时间复杂度是[(n-1)*O(1) + O(n)]/n,结果还是O(1)

本题批注:
删除一个节点时,并不一定要删除节点本身,可删除它的下一个
删除一个节点,要free或delete,并且置为NULL

typedef struct ListNode {
    int val;
    struct ListNode* next;
} ListNode;
// 如果要找到待删除节点的前一结点就是O(n),
// 要想实现O(1)就不能查找,因此我们用待删除节点保存它下一节点的内容,然后删除下一节点
ListNode* DeleteElement(ListNode* head, ListNode* pToDeleted) {
    if (head == NULL || pToDeleted == NULL)
        return head;
    // 只有一个节点
    if (head == pToDeleted) {
        delete pToDeleted;
        head = NULL;
        pToDeleted = NULL;
        return NULL;
    }
    if (pToDeleted->next == NULL) {
        // 待删除的为最后一个节点
        ListNode* pNode = head;
        while (pNode->next != pToDeleted) // 常规方法找到待删除前一结点
            pNode = pNode->next;
        pNode->next = NULL;
        delete pToDeleted;
        pToDeleted = NULL;
    } else {
        // 要删除的节点不是尾节点
        ListNode* pNext = pToDeleted->next;
        pToDeleted->val = pNext->val;
        pToDeleted->next = pNext->next;
        delete pNext;
        pNext = NULL;
    }
    return head;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值