Java双链表的最后一个节点将无法正确指向列表

时间:2019-09-10 18:48:14

标签: java

我想在列表的末尾添加一个节点,但似乎无法连接第一个节点及其结束位置之间的链接。

我知道我的逻辑是不正确的,因为要使其正常工作的唯一方法是要求我覆盖最后一个并将其分配为null。如果我不这样做,则程序将进入无限循环,因为我的猜测是没有一个节点为null才能阻止循环结束。我认为第20行将创建该新对象以保留null,然后第21行将temp链接回该对象。

public class LinkedListDeque {

public DoubleNode first = new DoubleNode();
public DoubleNode last = new DoubleNode();
public DoubleNode temp;
public int N;


private class DoubleNode {

    String item;
    int counter = 0;
    DoubleNode next;
    DoubleNode prev;
    DoubleNode last;

    DoubleNode() {
    }

    DoubleNode(String i) {
        this.item = i;
    }

}


public void enqueue(String item) {

    temp = getNode(null); //returns pointer to last node in "first"

    System.out.println("\nenqueue\n***********");

    DoubleNode oldlast;        

    oldlast = temp;
    temp.item = item;

    last = temp;

    System.out.println("last = " + last.item);  // = last item
    System.out.println("temp = " + temp.item);  // = last item    

line 20     temp = new DoubleNode();    
line 21     temp = oldlast;    

    DoubleNode last;              //will go into infinite loop w/out 
    last = temp;                  //these two lines

    System.out.println("last = " + last.item);   // = null
    System.out.println("temp = " + temp.item);   // = null

    if (isEmpty()) {            //returns true if first == null
        first = last;
    } else {
        oldlast.next = last;

    }
    N++;
 }

}

3 个答案:

答案 0 :(得分:2)

我认为您的实现应如下所示:

public final class LinkedListDeque {

    private Node root;
    private int size;

    public void enqueue(String val) {
        Node node = new Node(val);

        if (size == 0) {
            node.next = node;
            node.prev = node;
            root = node;
        } else {
            Node last = root.prev;

            last.next = node;
            node.prev = last;
            node.next = root;
            root.prev = node;
        }

        size++;
    }

    public String dequeue() {
        if (size == 0)
            throw new NoSuchElementException();

        String val = root.val;

        if (size == 1) {
            root.next = null;
            root.prev = null;
            root = null;
        } else {
            Node head = root.next;

            root.prev.next = head;
            head.prev = root.prev;
            root.next = null;
            root.prev = null;
            root = head;
        }

        size--;
        return val;
    }

    private static class Node {

        private final String val;
        private Node next;
        private Node prev;

        public Node(String val) {
            this.val = val;
        }
    }

}

答案 1 :(得分:1)

如果LinkedList正确维护了第一个和最后一个,则无需进行任何遍历即可将新节点放在最后。您只需要在新节点旁边设置当前倒数第二个节点,并在当前倒数第二个节点之前设置新节点,然后用新节点替换当前最后一个节点。

出队时,只要确保先清除last.getNext() == null的第一个和最后一个,就可以正确设置下一个入队的第一个和最后一个。

public class LinkedListDequeue<T> {
    private DoubleNode first;   // First node
    private DoubleNode last;    // Last node
    private size = 0;

    public static class DoubleNode<T> {
       private T value;
       private DoubleNode prev;
       private DoubleNode next;

       ...
    }

    public DoubleNode enqueue(DoubleNode<T> node) {
        if (first == null) {
            // If empty set node to the first and last node
            first = last = node;
        } else {
            // Set the current last node next -> new node and then the
            // new node previous to the last and then set the new node
            // as last.
            last.setNext(node);
            node.setPrev(last);             
            last = node;    
        }

        size++;
        return node;
    }

    public DoubleNode enqueue(T value) {
        return enqueue(new DoubleNode(value));
    }
}

答案 2 :(得分:0)

理论上,
通过遍历列表获取最后一个节点
分配last =最后一个节点
制作新对象()
分配新对象= last.next,它将新对象链接到原始列表并使它= null

但这实际上不起作用。这个想法多么简单,却很难应用