面试题18:删除链表的节点
问题
在O(1)的时间内删除链表节点,给定单项链表的头指针和一个节点指针,定义一个函数在O(1)时间内删除该节点。
void DeleteNode(Node** pListHead, Node* pToBeDeleted);
思路
如果我们把下一个节点的内容复制到需要删除的节点上覆盖原有的内容,再把下一个节点删除,就OK了。
总的复杂度是[(n-1)*O(1)+O(n)]/n。
注意
- 删除的节点在链表的尾部的情况。
- 只有一个头节点的情况。
- 因为可能会删除头结点,所以传入指向指针的指针。
参考代码
#include <iostream>
using namespace std;
struct Node
{
int val;
Node* next;
Node(int i,Node* next = nullptr):val(i),next(next){ }
};
void show(Node** pListHead);
void DeleteNode(Node** pListHead, Node* pToBeDeleted);
int main()
{
int input = 0;
cin >> input;
while(input != -1)
{
Node* n1 = new Node(1);
Node* n2 = new Node(2);
Node* n3 = new Node(3);
Node** head = &n1;
n1->next = n2;
n2->next = n3;
if(input == 1)
DeleteNode(head,n1);
if(input == 2)
DeleteNode(head,n2);
if(input == 3)
DeleteNode(head,n3);
show(head);
cin >> input;
}
return 0;
}
void show(Node** pListHead)
{
Node* node = *pListHead;
while(node)
{
cout<<node->val;
node=node->next;
}
cout<<endl;
return;
}
void DeleteNode(Node** pListHead, Node* pToBeDeleted)
{
if(pListHead == nullptr || pToBeDeleted == nullptr)
return;
if(pToBeDeleted->next != nullptr)
{
Node* pNext = pToBeDeleted->next;
pToBeDeleted->val = pNext->val;
pToBeDeleted->next = pNext->next;
delete pNext;
pNext = nullptr;
}
else if(*pListHead == pToBeDeleted)
{
delete pToBeDeleted;
pToBeDeleted = nullptr;
*pListHead = nullptr;
}
else
{
Node* pNode = *pListHead;
while(pNode->next != pToBeDeleted)
pNode = pNode->next;
pNode->next = nullptr;
delete pToBeDeleted;
pToBeDeleted = nullptr;
}
return;
}