今天遇到一个关于哨兵节点的问题,废话不多说直接上图;

当不使用哨兵节点,只是单纯的在原有链表上进行删除倒数第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二叉树的哨兵节点

使用情况:①插入和删除元素时也会出现使用哨兵节点的情况。