利用哨兵节点解决单链表问题

2,763 阅读1分钟

单链表

单链表node结构
单链表node结构

next包含指针

ListNode sentinel = new ListNode(0);//定义一个哨兵节点
sentinel.next = head; //sentinel.next 是数据的引用  这里相当与sentinel.next指向head;

203.移除链表元素

题目描述

删除链表中等于给定值val的所有节点

哨兵节点的利用

当要删除的一个或多个节点位于链表的头部时,可以利用哨兵节点,使链表标准化,即使链表永不为空,永不无头,简化插入和删除的操作。

  • 可以定义一个哨兵节点,作为一个伪头,假设它是sentinel:ListNode sentinel = new ListNode(0);
  • 让它指向“真头”head:sentinel.next = head;
  • 定义两个指针,一个为前向指针prev,一个为当前指针curr。
    • curr的值如果就是指定值,让prev的下一节点指向当前节点的下一系节点。
    • curr的值如果不是指定值,就让代表上一节点的指针prev指向当前指针。
    • curr始终是要向后遍历的。
  • 最后返回sentinel.next。(prev和sentinel指向同一地址,prev已经将链表操作完成)
   public ListNode sentinelRemove(ListNode head,int val){
       //创建哨兵节点,指向head
       ListNode sentinel = new ListNode(0);
       sentinel.next = head;
       //定义两个指针,前向指向哨兵节点,当前指向head
       ListNode prev = sentinel;
       ListNode curr = head;
       while(curr!=null){
           if(curr.val == val){
               //当前节点值就是指定值,则让上一个节点的next指向下一个节点(跳过当前节点)
               prev.next = curr.next;
           }else{
               //上一个节点向后移
               prev = curr;
           }
           //遍历下一节点
           curr = curr.next;
       }
       //返回哨兵节点的下一节点(空节点的下一个节点)
       return sentinel.next;
   }