Java 我的';头部';我自己的LinkedList类中的节点

Java 我的';头部';我自己的LinkedList类中的节点,java,data-structures,Java,Data Structures,我已经用Node first和last编写了自己的链接类代码,因为存在Node last,所以当我试图在main方法中手动创建LinkedList并对其进行测试时,遇到了有关引用和指针操作的问题 我非常熟悉在“addFirst”、“addLast”和“remove”方法中实现的递归,但现在不知何故,在addFirst方法之后,对节点first的引用变为null public class LinkedList<T> { Node first,last,temp; publi

我已经用Node first和last编写了自己的链接类代码,因为存在Node last,所以当我试图在main方法中手动创建
LinkedList
并对其进行测试时,遇到了有关引用和指针操作的问题

我非常熟悉在“addFirst”、“addLast”和“remove”方法中实现的递归,但现在不知何故,在addFirst方法之后,对节点first的引用变为null

public class LinkedList<T> {
  Node first,last,temp;

   public class Node{
     T value;
     Node next;

     public Node(T value, Node next) {
        this.value = value;
        this.next = next;
     }

     public String toString(){
        if(next == null){
            return value.toString();
        }
        else{
            return value.toString() + " " + next.toString();
        }
     }

     public T getLL(int index){
        if(index == 0){
            return value;
        }
        if(next == null){
            throw new 
               IndexOutOfBoundsException("have reached the end of the list, none found");
        }
        return next.getLL(index-1);
     }

     public T removeLL(int x){
        if(x == 1){
            T value = next.value;
            next = next.next;
            return value;
        }
        else if(next == null){
            throw new 
              IndexOutOfBoundsException("have reached the end of the list, none found");
        }
        else{
            return next.removeLL(x-1);
        }
     }
  }

  public LinkedList(T value) {

    temp =  new Node(value,null);
    first = new Node(value,null);
    last = temp;
  }

  public static void main(String[] args) {
    /**
     * [120,110,100,90,80];
     */
    LinkedList L = new LinkedList(100);
    L.addFirst(110);
    L.addFirst(120);
    L.addLast(90);
    L.addLast(80);
    System.out.println(L.size());
    System.out.println(L.remove(0));
    System.out.println(L.last.toString());
    //return null which causes the remove method not to work.
    System.out.println(L.first);
  }

  public void addFirst(T value){
    first = new Node(value,first);
  }

  public void addLast(T value){
    Node p = first;
    if( p == null){
        first = last = new Node(value,null);
    }

    while(p.next!= null){
        p = p.next;
    }
    last.next = new Node(value,null);
    last = new Node(value,null);

  }

  public T get(int index){
    if(first == null){
        throw new IndexOutOfBoundsException("empty list");
    }

    return first.getLL(index);


  }

  public int size(){
    int c = 0;
    while(first != null){
        first = first.next;
        c++;
    }
    return c;
  }

  public T remove(int x){
    if(first == null){

        throw new IndexOutOfBoundsException("Tried to remove from empty list");
    }
    if (x == 0) {
        T value = first.value;
        first = first.next;
        return value;
    }
    return first.removeLL(x);
  }
}
公共类链接列表{
第一个节点、最后一个节点、临时节点;
公共类节点{
T值;
节点下一步;
公共节点(T值,下一个节点){
这个值=值;
this.next=next;
}
公共字符串toString(){
if(next==null){
返回值.toString();
}
否则{
返回值.toString()+“”+next.toString();
}
}
公共T getLL(整数索引){
如果(索引==0){
返回值;
}
if(next==null){
抛出新的
IndexOutOfBoundsException(“已到达列表末尾,未找到”);
}
返回next.getLL(索引-1);
}
公共T拆除(int x){
如果(x==1){
T值=next.value;
next=next.next;
返回值;
}
else if(next==null){
抛出新的
IndexOutOfBoundsException(“已到达列表末尾,未找到”);
}
否则{
返回下一步。移除(x-1);
}
}
}
公共链接列表(T值){
temp=新节点(值,null);
第一个=新节点(值,null);
最后=温度;
}
公共静态void main(字符串[]args){
/**
* [120,110,100,90,80];
*/
LinkedList L=新的LinkedList(100);
L.addFirst(110);
L.addFirst(120);
L.addLast(90);
L.addLast(80);
System.out.println(L.size());
系统输出println(L.remove(0));
System.out.println(L.last.toString());
//返回null,这会导致remove方法不工作。
System.out.println(L.first);
}
公共void addFirst(T值){
第一个=新节点(值,第一个);
}
公共void addLast(T值){
节点p=第一;
if(p==null){
第一个=最后一个=新节点(值,null);
}
while(p.next!=null){
p=p.next;
}
last.next=新节点(值,null);
last=新节点(值,null);
}
公共T获取(整数索引){
if(first==null){
抛出新的IndexOutOfBoundsException(“空列表”);
}
return first.getLL(索引);
}
公共整数大小(){
int c=0;
while(第一个!=null){
first=first.next;
C++;
}
返回c;
}
公共T删除(int x){
if(first==null){
抛出新的IndexOutOfBoundsException(“试图从空列表中删除”);
}
如果(x==0){
T值=first.value;
first=first.next;
返回值;
}
首先返回。移除(x);
}
}

我希望节点首先指向
LinkedList
的第一个元素,而不是指向
null
。同时,这不会影响节点last的指针。

看起来像是
AddLast
函数中的问题。你在名单上。 难道不是这样吗

public void addLast(T value){
   Node p = first;
   if( p == null){
      first = last = new Node(value,null);
   }

   while(p.next!= null){
     p = p.next;
   }
   p.next = new Node(value,null);
   last = p.next;
   //last = new Node(value,null);
 }
更新关于您的评论和更新的答案

  • 您的尺寸函数错误:

    public int size(){
      int c = 0;
      while(first != null){
        first = first.next; // <-- now first point to the last and length is 1
        c++;
      }
      return c;
    }
    
    public int size(){
    int c=0;
    while(第一个!=null){
    
    first=first.next;//很抱歉代码块的格式,现在我甚至不知道如何删除该问题并编写一个新的问题。我运行了您的代码。first不会像您的文本所建议的那样变为null。并且NullPointerException不会在您告诉我们它被抛出的地方抛出。它被抛出removeLL,消息说:已到达列表的末尾,未找到"。顺便说一句,我不知道这个方法应该做什么。这是肯定的,它不会删除任何内容。在构造函数中,
    first
    last
    可能会指向同一个
    节点
    。另外,
    temp
    是什么?它在哪里使用过吗?
    removeLL
    可能会返回最后一个元素,但它不会删除它。请注意,我必须删除
    System.out.println(L.size());
    ,因为没有size()方法。您的函数
    AddLast
    看起来可疑。尝试对添加到末尾的行进行注释,看看会发生什么。可疑行:
    last.next=new Node(value,null);last=new Node(value,null);
    谢谢您的帮助。我认为这两种方法都可以,原始代码最后一个。下一个是指新添加的元素,然后更改了指向该元素的节点最后一个指针,所以这没什么问题。我真正的问题是,节点第一个指向null。