题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(l)时间删除该结点。链表结点与函数的定义如下:
转载请注明出处: http://blog.csdn.net/lsh_2013/article/details/45674123
struct ListNode{
int m_nValue;
ListNode *m_pNext;
};
void DeleteNode(ListNode **pListHead, ListNode *pToBeDeleted);
把下一个结点的内容复制到需要删除的结点上覆盖原有的内容,再把下一个结点删除,那就相当于把当前需要删除的结点删除了。
接下来我们分析这种思路的时间复杂度。对于n-1个非尾结点而言,我们可以在。O(1)时间内把下一个结点的内存复制覆盖要删除的结点,并删除下一个结点;对于尾结点而言,由于仍然需要顺序查找,时间复杂度是O(n)因此总的平均时间复杂度是[(n-l)*O(1)+O(n)}/n结果还是0(1),符合题目要求。
代码如下:
void DeleteNode(ListNode **pListHead, ListNode *pToBeDeleted)
{
if (pListHead==NULL||pToBeDeleted==NULL)
{
printf("func DeleteNode err!");
return;
}
if (pToBeDeleted->m_pNext!=NULL)//要删除的结点不是尾结点,是中间结点
{
pToBeDeleted->m_nValue=pToBeDeleted->m_pNext->m_nValue;
pToBeDeleted->m_pNext=pToBeDeleted->m_pNext->m_pNext;
delete pToBeDeleted->m_pNext;
pToBeDeleted->m_pNext=NULL;
}
else if (*pListHead==pToBeDeleted)//链表仅有一个结点,既是首结点也是尾结点
{
delete pToBeDeleted;
pToBeDeleted=NULL;
*pListHead=NULL;
}
else//要删除的结点是尾结点,且尾结点之前有其他结点
{
ListNode *pNode=*pListHead;//定义一个指针变量指向头结点
//找到尾结点的前驱
while(pNode->m_pNext!=pToBeDeleted)
{
pNode=pNode->m_pNext;
}
pNode->m_pNext=NULL;
delete pToBeDeleted;
pToBeDeleted=NULL;
}
}
注明:要删除的结点的确在链表中。
转载请注明出处: http://blog.csdn.net/lsh_2013/article/details/45674123