题目描述
给定单向链表的头指针和一个节点指针,定义一个函数在 O(1) 时间内删除该节点。
算法分析
如果顺序查找节点并删除,其时间复杂度为 O(n),无法满足题目要求。为此将待删除节点 p 的下一个节点 p_Next 的信息复制给 p , 删除 p_Next 即可满足 O(1) 的复杂度要求 。但要注意特殊情况的处理
- 链表只有一个节点,待删除节点为头结点时:将头指针赋值为nullptr
- 待删除节点为尾结点时,采用顺序查找节点的方式删除
程序代码
#include<iostream>
#include "LinkList.h"
using std::cout;
using std::endl;
void PrintList(Node<int> *p)
{
while(p)
{
cout << p->data << " ";
p = p->Next;
}
}
void DeleteNode(Node<int>** pListHead, Node<int>* pToBeDeleted)
{
if(!(*pListHead) || !pToBeDeleted)
return;
if(*pListHead == pToBeDeleted && (*pListHead)->Next == nullptr)//删除的是头结点,且链表只有一个节点
{
delete pToBeDeleted;
*pListHead = nullptr;
}
else if(pToBeDeleted->Next == nullptr)//删除的是尾结点
{
//顺序查找
Node<int> *p = *pListHead;
while(p->Next != pToBeDeleted)
{
p = p->Next;
}
delete p->Next;
p->Next = nullptr;
}
else//删除的是中间节点
{
Node<int> *p_next = pToBeDeleted->Next;
pToBeDeleted->data = p_next->data;
pToBeDeleted->Next = p_next->Next;
delete p_next;
}
}
void main()
{
int brr[10] = {1,2,3,4,5,6,7,8,9,10};
LinkList<int> b(10,brr);
Node<int> *pListHead = b.GetHead()->Next;
//Node<int> *pToBeDeleted = pListHead->Next->Next->Next;
Node<int> *pToBeDeleted = pListHead;
//Node<int> *pToBeDeleted = pListHead->Next->Next->Next->
// Next->Next->Next->Next->Next->Next;
DeleteNode(&pListHead,pToBeDeleted);
PrintList(pListHead);
system("pause");
return;
}