剑指offer刷题———在O(1)时间内删除链表结点

问题重述:

题目:在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;
	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值