2014-10-28 3 views
0
import java.util.*; 

public class MyTwoWayLinkedList<E> extends java.util.AbstractSequentialList<E> { 
    private Node<E> head, tail; 
    private int size = 0; 
    private List<E> list; 

    /** Create a default list */ 
    public MyTwoWayLinkedList() { 
    list = new LinkedList<E>(); 
    } 

    public MyTwoWayLinkedList(E[] objects) { 
    list = new LinkedList<E>(); 

    for (int i = 0; i < objects.length; i++) 
     add(objects[i]); 
    } 

    /** Return the head element in the list */ 
    public E getFirst() { 
    if (size == 0) { 
     return null; 
    } 
    else { 
     return head.element; 
    } 
    } 

    /** Return the last element in the list */ 
    public E getLast() { 
    if (size == 0) { 
     return null; 
    } 
    else { 
     return tail.element; 
    } 
    } 

    /** Add an element to the beginning of the list */ 
    public void addFirst(E e) { 
    Node<E> newNode = new Node<E>(e); // Create a new node 
    newNode.next = head; // link the new node with the head 
    head.previous = newNode; //link the old node with new head 
    head = newNode; // head points to the new node 
    size++; // Increase list size 

    if (tail == null) // the new node is the only node in list 
     tail = head; 
    } 

    /** Add an element to the end of the list */ 
    public void addLast(E e) { 
    Node<E> newNode = new Node<E>(e); // Create a new for element e 

    if (tail == null) { 
     head = tail = newNode; // The new node is the only node in list 
    } 
    else { 
     tail.next = newNode;// Link the new with the last node 
     newNode.previous = tail; 
     tail = tail.next; // tail now points to the last node 
    } 

    size++; // Increase size 
    } 

    @Override /** Add a new element at the specified index 
    * in this list. The index of the head element is 0 */ 
    public void add(int index, E e) { 
    if (index == 0) { 
     addFirst(e); 
    } 
    else if (index >= size) { 
     addLast(e); 
    } 
    else { 
     Node<E> current = tail; 
     for (int i = size - 1; i > index; i--) { 
     current = current.previous; 
     } 
     Node<E> temp = current.next; 
     current.next = new Node<E>(e); 
     (current.next).previous = current; 
     (current.next).next = temp; 
     size++; 
    } 
    } 

    /** Remove the head node and 
    * return the object that is contained in the removed node. */ 
    public E removeFirst() { 
    if (size == 0) { 
     return null; 
    } 
    else { 
     Node<E> temp = head; 
     head = head.next; 
     head.previous = null; 
     size--; 
     if (head == null) { 
     tail = null; 
     } 
     return temp.element; 
    } 
    } 

    /** Remove the last node and 
    * return the object that is contained in the removed node. */ 
    public E removeLast() { 
    if (size == 0) { 
     return null; 
    } 
    else if (size == 1) { 
     Node<E> temp = head; 
     head = tail = null; 
     size = 0; 
     return temp.element; 
    } 
    else { 

     Node<E> temp = tail; 
     tail = tail.previous; 
     tail.next = null; 
     size--; 
     return temp.element; 
    } 
    } 

    @Override /** Remove the element at the specified position in this 
    * list. Return the element that was removed from the list. */ 
    public E remove(int index) { 
    if (index < 0 || index >= size) { 
     return null; 
    } 
    else if (index == 0) { 
     return removeFirst(); 
    } 
    else if (index == size - 1) { 
     return removeLast(); 
    } 
    else { 
     Node<E> previous = tail; 

     for (int i = size - 1; i > index; i--) { 
     previous = previous.previous; 
     } 

     Node<E> current = previous.next; 
     (current.next).previous = previous; 
     previous.next = current.next; 
     size--; 
     return current.element; 
    } 
    } 

    @Override /** Override toString() to return elements in the list */ 
    public String toString() { 
    StringBuilder result = new StringBuilder("["); 

    Node<E> current = tail; 
    for (int i = size - 1; i > 0; i--) { 
     result.append(current.element); 
     current = current.previous; 
     if (current != null) { 
     result.append(" ,"); // Separate two elements with a comma 
     } 
     else { 
     result.append("["); // Insert the closing ] in the string 
     } 
    } 

    return result.toString(); 
    } 

    @Override /** Clear the list */ 
    public void clear() { 
    size = 0; 
    head = tail = null; 
    } 

    @Override /** Override iterator() defined in Iterable */ 
    public ListIterator<E> listIterator() {  
    Node<E> current = head; // Current index 

    return list.listIterator(); 
    } 

    @Override /** Override iterator() defined in Iterable */ 
    public ListIterator<E> listIterator(int index) {  
    Node<E> current = head; // Current index 
    for (int i = 0; i < index; i++) { // sets current int to the parameter 
     current = current.next; 
     } 

    return list.listIterator(); 
    } 

    @Override 
    public int size() 
    { 
    return size; 
    } 

    public class Node<E> { 
    E element; 
    Node<E> next; 
    Node<E> previous; 

    public Node(E element) { 
     this.element = element; 
    } 
    } 
} 

이것은 내 원래 클래스이며 아래에 테스트 사례가 포함되어 있지만 먼저 문제를 설명해 드리겠습니다. 이중 연결 목록을 만들고 역순으로 반복하려고합니다. 그러나 그냥 요소를 목록에 추가하여 Null 포인터 예외가 나타납니다. 지금 약 2 시간 동안 addFirst 메소드의 코드 섹션을 살펴 보았습니다. 로직 오류가 표시되지 않습니다 (도움이되지는 않습니다). 도움을주십시오!addFirst (E e) 이중 링크 목록 (Null 포인터 예외)

여기 내 약속대로 테스트 케이스입니다.

public class TestMyLinkedList { 
    /** Main method */ 
    public static void main(String[] args) { 
    // Create a list for strings 
    MyTwoWayLinkedList<String> list = new MyTwoWayLinkedList<String>(); 

    // Add elements to the list 
    list.add("America"); // Add it to the list 
    System.out.println("(1) " + list); 

    list.add(0, "Canada"); // Add it to the beginning of the list 
    System.out.println("(2) " + list); 

    list.add("Russia"); // Add it to the end of the list 
    System.out.println("(3) " + list); 

    list.addLast("France"); // Add it to the end of the list 
    System.out.println("(4) " + list); 

    list.add(2, "Germany"); // Add it to the list at index 2 
    System.out.println("(5) " + list); 

    list.add(5, "Norway"); // Add it to the list at index 5 
    System.out.println("(6) " + list); 

    list.add(0, "Poland"); // Same as list.addFirst("Poland") 
    System.out.println("(7) " + list); 

    // Remove elements from the list 
    list.remove(0); // Same as list.remove("Australia") in this case 
    System.out.println("(8) " + list); 

    list.remove(2); // Remove the element at index 2 
    System.out.println("(9) " + list); 

    list.remove(list.size() - 1); // Remove the last element 
    System.out.print("(10) " + list + "\n(11) "); 

    for (String s: list) 
     System.out.print(s.toUpperCase() + " "); 

    list.clear(); 
    System.out.println("\nAfter clearing the list, the list size is " 
     + list.size()); 
    } 
} 

답변

0

Double Linked List를 자체 구현 한 이유에서 LinkedList를 사용하는 이유가 확실하지 않습니다. 그러나 addFirst 메서드에 대한 질문에 관해서는 다음과 같은 의견과이 솔루션에 어떻게 접근 할 것인지 예를 들어 있습니다.

addFirst 메서드를 호출하면 Head가 null입니다. 헤드가 새 노드로 초기화되지 않았습니다. 따라서 newNode.next = head;은 실제로 newNode.next = null;입니다. 널 포인터 예외가 있습니다. 상상할 수 있습니다!

public void addFirst (E e) 
{ 
    Node<E> newNode = new Node<E>(e); //create new node 

    if (head != null){ //if head exists 
     newNode.next = head; //the new node's next link becomes the old head 
    } 
     head = newNode; //the new head is the new node 

    if (tail == null){ //if the tail is non existent ie head the only object in list 
     tail = head; //the head and the tail are the same 
     head.next = tail; //the 'next' value of head will be tail 
    } 
     head.prev = tail; //the previous node to head will always be tail 
     size++; 
    } 
}