面试题13:在O(1)时间删除链表结点
题目:给定单向链表的头指针和一个结点指针,定义一个函数在 O(1)时间删除该结点。链表结点与函数的定义如下:
struct ListNode
{int value;ListNode *next;
};void DeleteNode(ListNode ** pListHead, ListNode *pToBeDeleted);
代码如下:
struct ListNode
{int value;ListNode *next;
};void DeleteNode(ListNode ** pListHead, ListNode *pToBeDeleted)
{if (!pListHead || !pToBeDeleted) return;//要删除的结点不是尾结点if (pToBeDeleted->next != nullptr){ListNode *pNext = pToBeDeleted->next;pToBeDeleted->value = pNext->value;pToBeDeleted->next = pNext->next;delete pNext;pNext = nullptr;}//链表只有一个结点,删除头结点(也是尾结点)else if (*pListHead == pToBeDeleted){delete pToBeDeleted;pToBeDeleted = nullptr;*pListHead = nullptr;}//链表中有多个结点,删除尾结点else{ListNode *pNode = *pListHead;while (pNode->next != pToBeDeleted){pNode = pNode->next;}pNode->next = nullptr;delete pToBeDeleted;pToBeDeleted = nullptr;}
}
测试用例:
● 功能测试(从有多个结点的链表的中间删除一个结点,从有多个结点的链表中删除头结点,从有多个结点的链表中删除尾结点,从只有一个结点的链表中删除唯一的结点)。
● 特殊输入测试(指向链表头结点指针的为 NULL 指针,指向要删除的结点为NULL指针)。
本题考点:
● 考查应聘者对链表的编程能力。
● 考查应聘者的创新思维能力。这道题要求应聘者打破常规的思维模式。当我们想删除一个结点时,并不一定要删除这个结点本身。可以先把下一个结点的内容复制出来覆盖被删除结点的内容,然后把下一个结点删除。这种思路不是很容易想到的。
● 考查应聘者思维的全面性。即使应聘者想到删除下一个结点这个办法,也未必能通过这轮面试。应聘者要全面考虑到删除的结点位于链表的尾部及输入的链表只有一个结点这些特殊情况。