Java Mithilfe von Knoten mit LinkedList

Ich habe durch einige standard-Codierung-interview, Fragen aus einem Buch, das ich vor kurzem gekauft, und ich stieß auf die folgende Frage und Antwort:

Implementieren Sie einen Algorithmus zu finden der N-TEN zum letzten element in einer verketteten Liste.

Hier ist die Antwort zur Verfügung gestellt:

public static LinkedListNode findNtoLast(LinkedListNode head, int n) { //changing LinkedListNode to ListNode<String>
        if(head == null || n < 1) {
            return null;
        }
        LinkedListNode p1 = head;
        LinkedListNode p2 = head;
        for(int j = 0; j < n-1; ++j) {
            if(p2 == null) {
                return null;
            }
            p2 = p2.next;
        }
        if(p2 == null) {
            return null;
        }
        while(p2.next != null) {
            p1 = p1.next;
            p2 = p2.next;
        }
        return p1;
    }

Verstehe ich den Algorithmus, wie es funktioniert, und warum die Listen in diesem Buch, wie seine Antwort, aber ich bin verwirrt darüber, wie Sie Zugang zu den LinkedListNodes zu senden, die als argument an die Methode. Ich weiß, dass ich haben, um eine LinkedListNode Klasse (da Java nicht bereits eine haben), aber ich kann nicht scheinen, um herauszufinden, wie das zu tun. Es ist frustrierend, weil ich das Gefühl, ich sollte wissen, wie dies zu tun. Hier ist etwas, was ich gearbeitet habe. Ich würde schätzen, keine Klärung. Sie können erweitern/Kommentar zu meinem code oder bieten Ihre eigenen alternativen. Danke.

class ListNode<E> {
    ListNode<E> next;
    E data;

    public ListNode(E value) {
        data = value;
        next = null;
    }

    public ListNode(E value, ListNode<E> n) {
        data = value;
        next = n;
    }

    public void setNext(ListNode<E> n) {
        next = n;
    }
}

public class MyLinkedList<E> extends LinkedList {
    LinkedList<ListNode<E>> list;
    ListNode<E> head;
    ListNode<E> tail;
    ListNode<E> current;
    ListNode<E> prev;

    public MyLinkedList() {
        list = null;
        head = null;
        tail = null;
        current = null;
        prev = null;
    }

    public MyLinkedList(LinkedList<E> paramList) {
        list = (LinkedList<ListNode<E>>) paramList; //or maybe create a loop assigning each ListNode a value and next ptr
        head = list.getFirst();
        tail = list.getLast(); //will need to update tail every time add new node
        current = null;
        prev = null;
    }

    public void addNode(E value) {
        super.add(value);
        //ListNode<E> temp = tail;
        current = new ListNode<E>(value);
        tail.setNext(current);
        tail = current;
    }

    public LinkedList<ListNode<E>> getList() {
        return list;
    }

    public ListNode<E> getHead() {
        return head;
    }

    public ListNode<E> getTail() {
        return tail;
    }

    public ListNode<E> getCurrent() {
        return current;
    }

    public ListNode<E> getPrev() {
        return prev;
    }


}

Wie kann die LinkedListNode Kopf von einer LinkedList?

Update: ich denke, ein Teil meiner Verwirrung kommt von dem, was in der main-Methode. Brauche ich zum erstellen einer LinkedList von ListNode? Wenn ich das tun würde, wie Verbinde ich die ListNodes zu einander? Wie würde ich das anschließen, ohne Sie mit einer LinkedList collection-Objekt? Wenn jemand mir zeigen könnte wie Sie, würde der code der main-Methode, ich glaube, das würde die Dinge in die genug Perspektive für mich zu lösen meine Probleme. Hier ist meine neueste Versuch der main-Methode:

public static void main(String args[]) {
        LinkedList<ListNode<String>> list = new LinkedList<ListNode<String>>();
        //MyLinkedList<ListNode<String>> list = new MyLinkedList(linkedList);
        list.add(new ListNode<String>("Jeff"));
        list.add(new ListNode<String>("Brian"));
        list.add(new ListNode<String>("Negin"));
        list.add(new ListNode<String>("Alex"));
        list.add(new ListNode<String>("Alaina"));
        int n = 3;
        //ListIterator<String> itr1 = list.listIterator();
        //ListIterator<String> itr2 = list.listIterator();
        LinkedListNode<String> head = new LinkedListNode(list.getFirst(), null);
        //String result = findNtoLast(itr1, itr2, n);
        //System.out.println("The " + n + "th to the last value: " + result);
        //LinkedListNode<String> nth = findNtoLast(list.getFirst(), n);
        ListNode<String> nth = findNtoLast(list.getFirst(), n);
        System.out.println("The " + n + "th to the last value: " + nth);
    }

In einem Versuch, um die Knoten zu verbinden ohne Verwendung einer benutzerdefinierten LinkedList-Klasse, habe ich bearbeitet meine ListNode-Klasse, um die folgenden:

class ListNode<E> {
    ListNode<E> next;
    ListNode<E> prev; //only used for linking nodes in singly linked list
    ListNode<E> current; //also only used for linking nodes in singly linked list
    E data;
    private static int size = 0;

    public ListNode() {
        data = null;
        next = null;
        current = null;
        if(size > 0) { //changed from prev != null because no code to make prev not null
            prev.setNext(this);
        }
        size++;
    }
    public ListNode(E value) {
        data = value;
        next = null;
        current = this;
        System.out.println("current is " + current);
        if(size > 0) {
            prev.setNext(current);//this line causing npe
        }
        else
        {
            prev = current;
            System.out.println("prev now set to " + prev);
        }
        size++;
        System.out.println("after constructor, size is " + size);
    }

    public ListNode(E value, ListNode<E> n) {
        data = value;
        next = n;
        current = this;
        if(size > 0) {
            prev.setNext(this);
        }
        size++;
    }

    public void setNext(ListNode<E> n) {
        next = n;
    }
}

Als jetzt ist, wird das Programm laufen, bis es erreicht prev.setNext(current); in der single-argument-Konstruktor für ListNode. Weder Strom noch prev null ist an der Zeit, diese Zeile erreicht ist. Jede Beratung würde sehr geschätzt werden. Danke.

  • Wenn die Methode nicht statisch, es scheint, dass es Teil einer LinkedList-Klasse. Dann wäre es in der Lage, den Zugriff auf die (angenommene privaten) Bereich Kopf.
  • Ich sehe, dass Sie Unterklassen von java.util.LinkedList. Es macht nicht viel Sinn zu Unterklasse und dann setzen Sie Ihre eigene Knoten-Klasse. LinkedList hat bereits eine private Klasse namens Entry, das ist für diesen Zweck verwendet. Wie Sie erwähnen Sie keinen Zugang haben, können Sie es nicht, die den Algorithmus implementieren, die Sie gezeigt haben, mit einer LinkedList Unterklasse. Sie haben Ihre eigenen erstellen wie bereits gesagt in meiner Antwort.
  • Sehen Sie den Quellcode für die LinkedList in developer.classpath.org/doc/java/util/LinkedList-source.html, wenn Sie sind interessiert zu sehen, wie es funktioniert. Du wirst sehen, dass es eigentlich eine doppelt verkettete Liste (next und prev Referenzen). Dies ist notwendig, damit die Elemente entfernt werden aus der Mitte.
InformationsquelleAutor jeffkempf | 2014-12-30
Schreibe einen Kommentar