剑指Offer——删除链表中的节点

给定单向链表的头指针以及链表中的节点指针,要求在O(1)时间内删除该节点

这里我们假设给定要删除的节点一定位于链表内。否则的话如果需要确定链表中是否包含该节点,则要O(N)的时间。

在这里插入图片描述

删除链表中的一个节点有两个方法,方法一如上图(a),需要删除的是节点i,此时需要获得其前一个节点h,将h由原来指向i变为指向j,然后再删除i即可。
此法需要获得删除节点的上一个节点,对于本题,由于是单向链表,如果要获得节点h,需要从头遍历链表,时间复杂度为O(N),不符合要求。

既然不能获得待删除节点的上一个节点,我们可以打一下链表后方节点的主意。如图©,如果将节点j的元素拷贝到节点i,然后再删除节点j,则最终的效果跟删除节点i是一样的。

注意此法由于需要拷贝待删除节点i的下一个节点元素,如果i为尾节点,则无法拷贝,此时仍然需要从头遍历数组,找到i的前一个节点,用旧方法删除。

另外一个需要注意的是,如果链表中只有1个元素,则只需要将头指针至为空即可。

由于只有需要删除最后一个节点时才需要遍历链表,因此平均的时间复杂度仍然是O(1)

下方为实现代码:

void DeleteNodeInList(LinkList &List, ListNode *Node){
  if(List==nullptr||Node==nullptr) return;
  //假设输入的Node一定在链表中

  //当链表只有1个元素
  if(List==Node&&List->Next==nullptr){
    delete Node;
    List=nullptr;
    return;
  }

  //当删除节点为尾节点,需要从头遍历找到节点的前一个节点
  if(Node->Next==nullptr){
    ListNode *mPrev = List;
    while(mPrev->Next!=Node) mPrev = mPrev->Next;
    delete Node;
    mPrev->Next = nullptr;
    return;
  }

  //当删除节点为除尾节点以外

  ListNode *NodeToBeDel = Node->Next;//真实需要删除节点
  ListNode *NodeNext = NodeToBeDel->Next;//删除后Node的下一个节点

  Node->Value = NodeToBeDel->Value;
  Node->Next = NodeNext;
  delete NodeToBeDel;
  return;
  }

本题完整代码在这里

总结

本题难点在于,不能用以往方法来删除链表节点。
能够想到用删除下一个节点的方法,也要能够想到当链表只有1个元素和待删除节点在链表末尾的情况。

总之在处理关于链表的问题是,要处理好几个边界条件。分别是当链表或者节点为空、链表只有一两个元素、节点处于链表头或者链表尾的情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值