头部值设置为 null 但尾部值仍然显示

Head value set to null but tail value still gets displayed

在java链表中如果head=null则链表为空。但是,当我设置 head=null 并打印 tail 的值时,会显示该值。为什么我们说 head==null 意味着 LinkedList 是空的?为什么当链表应该为空时显示尾值?我们不应该检查 id(tail==null) 吗?

public class SinglyLinkedList{
  public Node head;
  public Node tail;
  public int size;

  public Node createLL(int num){
    Node node=new Node();
    node.value=num;
    node.next=null;
    head=node;
    tail=node;

    size=1;
    return head;
  }

  public void insertNode(int num,int location){
    Node node=new Node();
    node.value=num;
    
    if(head==null){//Check
      createLL(num);
      return;
    }

    else if(location==0){
      node.next=head;
      head=node;
    }

    else if(location>=size){
      node.next=null;
      tail.next=node;
      tail=node;
    }

    else{
      Node tempNode=head;
      int index=0;

      while(index<location-1){
        tempNode=tempNode.next;
        index++;
      }
     node.next=tempNode.next;
     tempNode.next=node;
    }
    size++;
  }

  public void traverse(){
    if(head==null){//Check
      System.out.println("The linked list is empty");
    }
    Node tempNode=head;
    for(int i=0;i<size;i++){
      System.out.print(tempNode.value);
      if(i!=size-1){
        System.out.print("->");
      }
      tempNode=tempNode.next;
    }
    System.out.println();
  }

  public void deleteNode(int location){
    if(head==null){//Check
      System.out.println("The linked list is not present");
      return;
    }

    else if(location==0){
      head=head.next;
      size--;
      if(size==0){
        tail=null;
      }
    }

    else if(location>=size){
      Node tempNode=head;
      for(int i=0;i<size-1;i++){
        tempNode=tempNode.next;
      }
      if(head==null){
        tail=null;
        size--;
        return;
      }
      tempNode.next=null;
      tail=tempNode;
      size--;
    }

    else{
      Node tempNode=head;
      int index=0;

      while(index<location-1){
        tempNode=tempNode.next;
        index++;
      }
      tempNode.next=tempNode.next.next;
      size--;
    }
  }

主要class

class Main {
  public static void main(String[] args) {
    SinglyLinkedList sLL=new SinglyLinkedList();
    sLL.createLL(5);
    sLL.insertNode(15, 1);
    sLL.insertNode(20, 2);
    sLL.insertNode(39, 3);
    sLL.insertNode(45, 4);

    sLL.traverse();
    
    sLL.head=null;
    System.out.println(sLL.tail.value);
  }
}

输出: 5->15->20->39->45

45

head 成为 null 仅意味着您无法再达到第一个 Node。这也意味着您无法通过 next 引用访问整个链,因为您没有起点。
允许垃圾收集器“释放”所有不再可达的对象。在您的情况下,除了 tail 节点之外的所有节点,因为您仍然在 SinglyLinkedList.

中保留对它的引用

所以实际上您有一个空的 LinkedList,因为您无法再正确访问它。但是您仍然保持 tail 节点处于活动状态,因为您引用了它。正确的解决方案是将 tail 也设置为 null,这样垃圾收集器也可以释放该节点。

通过该分配,您使列表实例不一致。一个空列表将 both 它的 headtail 成员设置为 null 它的 size 等于 0.

这就是为什么你不应该像那样改变你的 class 的成员。您甚至应该将它们设为私有,以防止调用者进行此类操作。如果你想有办法清空一个列表,然后为它创建一个适当的方法,它负责保持属性一致:

public void clear() {
    head = tail = null;
    size = 0;
}

在您的主代码中,只需调用 sLL.clear() 方法即可。

如果您保留对节点的引用,您将始终能够访问它。要真正失去一个节点,你必须摆脱所有对它的引用。