剑指offer 3.3 代码的完整性3- 在O(1)时间删除链表结点

面试13:在O(1)时间删除链表结点

题目:给定链表的头指针和一个结点指针,在O(1)时间删除该结点。链表结点的定义如下:

struct ListNode

{

      int        m_nKey;

      ListNode*  m_pNext;

};

函数的声明如下:

void DeleteNode(ListNodepListHeadListNodepToBeDeleted);

Google 面试题

在链表中删除一个结点,最常规的做法是从链表的头结点开始,顺序查找要删除的结点,找到之后再删除。由于需要顺序查找,时间复杂度自然就是O(n) 了。我们之所以需要从头结点开始查找要删除的结点,是因为我们需要得到要删除的结点的前面一个结点。


O(1)时间复杂度

如果要删除结点i,先把i的下一个结点j的内容复制到i,然后把i的指针指向j的下一个结点,此时再删除j,其效果刚好是吧结点i给删除了。O(1)

如果要删除的结点位于链表的尾部,没有下一个结点,仍需要从头开始遍历得到该节点的前序节点,并完成删除操作。O(n)

如果链表中只有一个结点,而我们又要删除链表的头结点,也是尾结点,此时删除结点之后,需要把链表的头结点设置为NULL.

 平均时间复杂度为[O(1) * (n - 1) + O(n)] / n = O(1)

///

// Delete a node in a list

// Input: pListHead - the head of list

//        pToBeDeleted - the node to be deleted

///

void DeleteNode(ListNodepListHeadListNodepToBeDeleted)

{

      if(!pListHead || !pToBeDeleted)

            return;

 

      // if pToBeDeleted is not the last node in the list

      if(pToBeDeleted->m_pNext != NULL)

      {

            // copy data from the node next to pToBeDeleted

            ListNodepNext = pToBeDeleted->m_pNext;

            pToBeDeleted->m_nKey = pNext->m_nKey;

            pToBeDeleted->m_pNext = pNext->m_pNext;

 

            // delete the node next to the pToBeDeleted

            delete pNext;

            pNext = NULL;

      } else if(pListHead == pToBeDeleted) {

            delete pToBeDeleted;

            pToBeDeleted = NULL;

            pListHead = NULL;

      }

      // if pToBeDeleted is the last node in the list

      else

      {

            // get the node prior to pToBeDeleted

            ListNodepNode = pListHead;

            while(pNode->m_pNext != pToBeDeleted)

            {

                  pNode = pNode->m_pNext;            

            }

 

            // deleted pToBeDeleted

            pNode->m_pNext = NULL;

            delete pToBeDeleted;

            pToBeDeleted = NULL;

      }

} 

上述代码基于一个假设:要删除的结点的确在链表中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值