问题重述:
题目:在O(1)时间内删除链表结点。给定单链表的头指针和一个结点指针,定义一个函数在O(1)时间内删除该结点。链表结点与函数的定义如下:
struct ListNode
{
int m_nValue;
ListNode* m_pNext;
};
void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted);
思路解析:
这道问题算是比较简单的,应全面考虑被删除结点在链表中的位置:
情况1:被删结点有前驱结点和后继结点
在这种情况下,只需要将被删结点的后继结点的值赋值给被删结点,同时将被删结点的后继改为后继结点的后继,然后将被删结点的后继结点删除即可。
情况2:被删结点没有前驱结点和后继结点
这种情况下,可能链表中就只有被删结点一个结点,将被删结点删除,同时将头节点的后继置为空即可。
情况3:被删结点有前驱结点但是没有后继结点
这种情况下,被删结点应属于链表中的最后一个结点,这样,就需要通过传统的方法,先找到被删结点的前驱结点,删除被删结点,并且将前驱结点的后继置为空即可。
虽然最后一种情况的时间复杂度未O(n),但是结合前两种情况,平均的时间复杂度还是未O(1).
代码实现:
struct ListNode
{
int m_nValue;
ListNode* m_pNext;
};
void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted)
{
//对pListHead和pToBeDeleted进行检验
if (!pListHead || !pToBeDeleted)
{
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;
}
}