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

题目: 在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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值