在o(1)时间内删除链表中结点

本文介绍了一种在O(1)时间复杂度内删除链表指定结点的方法,通过复制后续结点内容或特殊处理尾结点实现。提供了两种不同实现方式的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    题目:给定单向链表的头指针和一个结点指针,定义一个函数在o(1)时间删除该结点。
    解析:我们要删除结点i,先把i的下一个结点j的内容复制到i,然后把i的指针指向结点j的下一个结点。此时再删除结点j,效果刚好是把结点i给删除了。如果要删除的结点位于链表的尾部,那么他就没有下一个结点,我们仍然需要从链表的头结点开始,顺序遍历得到该结点的前序结点,并完成删除操作。如果删除的结点位于头结点,我们也需要特殊处理。以下代码是我自己写的。
#include<iostream>
using namespace std;

struct ListNode
{
	int val;
	ListNode *next;
};
void show(ListNode *pHead);

void appendTail(ListNode **pHead,int val)
{
	ListNode *pNew = new ListNode;
	pNew->next = NULL;
	pNew->val = val;
	if(*pHead == NULL)
	{
		*pHead = pNew;
	}
	else
	{
		ListNode *tmp = *pHead;
		while(tmp->next != NULL)
		{
			tmp = tmp->next;
		}
		tmp->next = pNew;
	}
}

void deleteNode(ListNode **pHead,ListNode *pCur)
{
	if(*pHead == NULL || pCur == NULL)
	{
		return;
	}
	//当删除元素在链表头部
	if(*pHead == pCur)
	{
		(*pHead)= pCur->next;
		delete pCur;
		return;
	}
	//当删除元素在末尾
	if(pCur->next == NULL)
	{
		ListNode *tmp = *pHead;
		while(tmp->next != pCur)
		{
			tmp = tmp->next;
		}
		tmp->next = NULL;
		delete pCur;
		return;
	}
	pCur->val = pCur->next->val;
	ListNode *p = pCur->next;
	pCur->next = p->next;
	delete p;
	return;
}

void show(ListNode *pHead)
{
	while(pHead)
	{
		cout<<pHead->val<<endl;
		pHead = pHead->next;
	}
}

int main(void)
{
	ListNode *pHead = NULL;
	for(int i = 0; i < 1; ++i)
	{
		appendTail(&pHead,i);
	}
	ListNode *pCur = pHead;
	for(int i = 0; i < 10; ++i)
	{
		pCur = pCur->next;
	}

	deleteNode(&pHead,pCur);
	show(pHead);
	system("pause");
	return 0;
}
剑指offer上的代码:
void deleteNode(ListNode **pListHead,ListNode *pVal)
{
	if(!pListHead || !pVal)
		return;
	if(pVal->next != NULL)
	{
		ListNode *pNext = pVal->next;
		pVal->val = pNext->val;
		pVal->next = pNext->next;
		delete pNext;
		pNext = NULL;
	}
	else if(*pListHead == pVal)
	{
		delete pVal;
		pVal = NULL;
		*pListHead = NULL;
	}
	else
	{	
		ListNode *pNode = *pListHead;
		while(pNode->next != pVal)
		{
			pNode = pNode->next;
		}
		pNode->next = NULL;
		delete pVal;
		pVal = NULL;
	}
}
时间复杂度分析:对于n-1个非尾节点而言,我们可以在o(1)时间内把下一个结点的内容复制到要删除的结点中,并删除下一个结点。对于尾结点而言,由于仍然需要顺序查找,时间复杂度为o(n)。因此总得时间复杂度还是o(1)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值