今天遇到一个关于哨兵节点的问题,废话不多说直接上图;
当不使用哨兵节点,只是单纯的在原有链表上进行删除倒数第n个节点的操作时。出现以上报错。并且在十几分钟内依然困住了我。由于上一篇刷题的经验告诉我,这次的问题估计出在使用空指针不当的情况,也就是说判断的情况不仔细清楚。因此我特意去增加了对fast指针指向下一处位置的目标进行非空判断。问题依然存在。解决问题的关键在于对链表边界的模糊,使得编译器不能确定导致的报错。修改如下:
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode*newhead=new ListNode(0,head);
ListNode* fast=head;
ListNode* slow=newhead;
if(!head){return head;}
for(int i=0;i<n;i++){
fast=fast->next;
}
while(fast){
fast=fast->next;
slow=slow->next; }
slow->next=slow->next->next;
return newhead->next;
}
};
修改为如上代码后,成功完成此题,鉴于此我做出以下对哨兵节点的归纳:
哨兵节点:
哨兵节点顾名思义:拥有检查和巡逻的功能,使用在编程中就是简化边界条件,从而防止对特殊条件的判断,使得代码简洁而优雅,在链表中最为常见。
1 单链表的哨兵节点
我上面列出来的这道题就是单链表中哨兵节点的运用。
使用情况:①头部或者尾部插入或者删除时
②修改前驱节点的后继指针
2 双链表的哨兵节点
使用情况:①需要能够在头部和尾部分别插入删除操作
②循环双链表
3二叉树的哨兵节点
使用情况:①插入和删除元素时也会出现使用哨兵节点的情况。