《剑指offer》第十八题:在O时间删除链表结点

Posted zsy-blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《剑指offer》第十八题:在O时间删除链表结点相关的知识,希望对你有一定的参考价值。

// 面试题18(一):在O(1)时间删除链表结点
// 题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该
// 结点。

#include <cstdio>
#include "List.h"

void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted)
{
    if (pListHead == nullptr || pToBeDeleted == nullptr)
        return;

    //多个节点, 且位于中间
    if (pToBeDeleted->m_pNext != nullptr)
    {
        ListNode* pNext = pToBeDeleted->m_pNext;
        pToBeDeleted->m_nValue = pNext->m_nValue;
        pToBeDeleted->m_pNext = pNext->m_pNext;
        delete pNext;
        pNext = nullptr;
    }
    //单节点,
    else if (*pListHead == pToBeDeleted)
    {
        delete pToBeDeleted;
        pToBeDeleted = nullptr;
        *pListHead = nullptr;
        
    }
    //多节点, 处于尾部
    else
    {
        ListNode* pNode = *pListHead;
        while (pNode->m_pNext != pToBeDeleted)
            pNode = pNode->m_pNext;

        pNode->m_pNext = nullptr;
        delete pToBeDeleted;
        pToBeDeleted = nullptr;
    }
}
技术图片
// ====================测试代码====================
void Test(ListNode* pListHead, ListNode* pNode)
{
    printf("The original list is: 
");
    PrintList(pListHead);

    printf("The node to be deleted is: 
");
    PrintListNode(pNode);

    DeleteNode(&pListHead, pNode);

    printf("The result list is: 
");
    PrintList(pListHead);
}

// 链表中有多个结点,删除中间的结点
void Test1()
{
    ListNode* pNode1 = CreateListNode(1);
    ListNode* pNode2 = CreateListNode(2);
    ListNode* pNode3 = CreateListNode(3);
    ListNode* pNode4 = CreateListNode(4);
    ListNode* pNode5 = CreateListNode(5);

    ConnectListNodes(pNode1, pNode2);
    ConnectListNodes(pNode2, pNode3);
    ConnectListNodes(pNode3, pNode4);
    ConnectListNodes(pNode4, pNode5);

    Test(pNode1, pNode3);

    DestroyList(pNode1);
}

// 链表中有多个结点,删除尾结点
void Test2()
{
    ListNode* pNode1 = CreateListNode(1);
    ListNode* pNode2 = CreateListNode(2);
    ListNode* pNode3 = CreateListNode(3);
    ListNode* pNode4 = CreateListNode(4);
    ListNode* pNode5 = CreateListNode(5);

    ConnectListNodes(pNode1, pNode2);
    ConnectListNodes(pNode2, pNode3);
    ConnectListNodes(pNode3, pNode4);
    ConnectListNodes(pNode4, pNode5);

    Test(pNode1, pNode5);

    DestroyList(pNode1);
}

// 链表中有多个结点,删除头结点
void Test3()
{
    ListNode* pNode1 = CreateListNode(1);
    ListNode* pNode2 = CreateListNode(2);
    ListNode* pNode3 = CreateListNode(3);
    ListNode* pNode4 = CreateListNode(4);
    ListNode* pNode5 = CreateListNode(5);

    ConnectListNodes(pNode1, pNode2);
    ConnectListNodes(pNode2, pNode3);
    ConnectListNodes(pNode3, pNode4);
    ConnectListNodes(pNode4, pNode5);

    Test(pNode1, pNode1);

    DestroyList(pNode1);
}

// 链表中只有一个结点,删除头结点
void Test4()
{
    ListNode* pNode1 = CreateListNode(1);

    Test(pNode1, pNode1);
}

// 链表为空
void Test5()
{
    Test(nullptr, nullptr);
}

int main(int argc, char* argv[])
{
    Test1();
    Test2();
    Test3();
    Test4();
    Test5();

    return 0;
}
测试代码

分析:代码假设要删除的节点的确在链表中。需要O(n)时间遍历链表才可以确认,可以讨论这个假设,考虑更为全面。

以上是关于《剑指offer》第十八题:在O时间删除链表结点的主要内容,如果未能解决你的问题,请参考以下文章

剑指Offer(Java版)第十六题:给定单向链表的头指针和一个结点指针,定义一个函数在O时间删除该结点。

剑指offer第十八题 顺时针打印矩阵

Java 剑指offer(17) 在O时间删除链表结点

在O时间删除链表结点——剑指offer

剑指Offer对答如流系列 - 在O时间删除链表结点

[剑指offer]面试题13:在O时间删除链表结点