删除链表中的节点,时间复杂度O(1)(剑指offer)

来源:互联网 发布:淘宝商城手机专卖店 编辑:程序博客网 时间:2024/06/03 21:57

题目: 在O(1)的时间内删除链表的节点

给定当链表的头指针和一个节点的指针,定义一个函数在O(1)的时间复杂度内删除该节点。

#include <cassert>#include <iostream>struct ListNode{    int mVal;    ListNode* mpNext;};/***@pHead 使用指针的指针,使得函数结束后pHead指向的节点有效*@val 待插入的值*/void addNodeToTail(ListNode** pHead, int val){    ListNode* pNewNode = new ListNode;    pNewNode->mVal = val;    pNewNode->mpNext = nullptr;    //如果头节点为空    if (*pHead == nullptr)    {        *pHead = pNewNode;    }    else    {    ListNode* pNode = *pHead;    while (pNode->mpNext != nullptr)        pNode = pNode->mpNext;        pNode->mpNext = pNewNode;    }}void destroyList(ListNode** pHead){   std::cout << "\nstart free memery..." << std::endl;    ListNode* pNode = *pHead;    while (*pHead != nullptr)    {            *pHead = (*pHead)->mpNext;        delete pNode;        pNode = *pHead;    }    std::cout << "free memery complete" << std::endl;}//从头到尾打印链表void printList(ListNode**pHead){    ListNode *pNode =*pHead;    while (pNode != nullptr)    {        std::cout << pNode->mVal << " ";    pNode = pNode->mpNext;    }}/***@pHead 指向链表的头节点*@val 要查找的元素*@return 指向查找的元素的位置*/ListNode* findVal(ListNode* pHead, int val){    ListNode* toBeFindList = nullptr;    ListNode* pNode = pHead;    while (pNode != nullptr && pNode->mVal != val)    {        pNode = pNode->mpNext;    }    toBeFindList = pNode;    return toBeFindList;}/***@pHead 指向链表头节点的指针*@pToBeDeleted 指向要删除的节点*/void deleteNode(ListNode** pHead, ListNode* pToBeDeleted){    //单链表为空, 直接返回    if (pHead == nullptr || (*pHead) == nullptr)        return;    //要删除的节点不是尾节点    if (pToBeDeleted->mpNext != nullptr)    {        ListNode* pNext = pToBeDeleted->mpNext;    pToBeDeleted->mVal = pNext->mVal;    pToBeDeleted->mpNext = pNext->mpNext;    delete pNext;    pNext = nullptr;    }    else if (*pHead == pToBeDeleted)  //链表中只有一个节点,删除该节点(即删除的节点是头节点或者尾节点)    {        delete pToBeDeleted;    pToBeDeleted = nullptr;    *pHead = nullptr;    }    else // 链表中有多个节点且删除的节点是尾节点    {     ListNode* pNode = *pHead;     while (pNode->mpNext != pToBeDeleted)     {         pNode =pNode->mpNext;     }     pNode->mpNext = nullptr;     delete pToBeDeleted;     pToBeDeleted = nullptr;    }}/***测试用例*注意元素0表示输入的结束标志,并不把它存在链表中*例如输入链表 1 2 3 4 0*/int main(int argc, char* argv[]){    std::cout << "\n--提示: 输入元素 0 为输入结束的标志" << std::endl;    ListNode* pHead = nullptr;    int val;    //val == 0为结束标志    while (std::cin >> val && val != 0)        addNodeToTail(&pHead,  val);    std::cout << "打印初始化链表:";    printList(&pHead);    std::cout << "\n输入要删除的元素 : ";    int find_val;    while (std::cin >> find_val && find_val != 0)    {        ListNode* toBeFindNode = findVal(pHead, find_val);        if (toBeFindNode != nullptr)        {        std::cout << "找到元素 " << find_val << " 并将它从链表中删除" << std::endl;        deleteNode(&pHead, toBeFindNode);            std::cout << std::endl << "链表中剩余的元素有: ";        printList(&pHead);    }    else    {       std::cout << "元素 " << find_val << " 不在链表中" << std::endl;       printList(&pHead);    }        std::cout << "\n输入要删除的元素 : ";    }   //释放申请的内存空间    destroyList(&pHead);    return 0;}
原创粉丝点击