2015-02-05 5 views
2

이중 연결 목록 형식을 구현하여 Deque 클래스 (양쪽 끝에 추가하고 추가 할 수있는 스택/큐)를 만들려고합니다.반복 가능 Deque NullPointerException

import java.util.Iterator; 

공용 클래스 양단 큐의 Iterable {

Node first; 
Node last; 
int size; 

public Deque() 
{ 
    first = null; 
    last = null; 
    size = 2; 

    first.next = last; 
    last.prev = first; 
} 

private class Node 
{ 
    Node next; 
    Node prev; 
    Item item; 
} 

private class ListIterator implements Iterator<Item> 
{ 
    private Node current = first; 

    public boolean hasNext() 
    { 
     return current.next != null; 
    } 
    public Item next() 
    { 
     Item item = current.item; 
     current = current.next; 
     return item; 
    } 
    public void remove() 
    { 
     /* not supported */ 
    } 
} 

public boolean isEmpty() 
{ 
    if(first == null&&last == null) 
     return true; 
    return false; 
} 

public int size() 
{ 
    return size; 
} 

public void addFirst(Item item) 
{ 
    Node oldfirst = first; 
    first = new Node(); 
    first.item = item; 
    first.next = oldfirst; 
    oldfirst.prev = first; 
    size++; 
} 

public void addLast(Item item) 
{ 
    Node oldlast = last; 
    last = new Node(); 
    last.item = item; 
    last.prev = oldlast; 
    oldlast.next = last; 
    size++; 
} 

public Item removeFirst() 
{ 
    Item item = first.item; 
    first = first.next; 
    size--; 
    return item; 
} 

public Item removeLast() 
{ 
    Item item = last.item; 
    last = last.next; 
    size--; 
    return item; 
} 

@Override 
public Iterator<Item> iterator() 
{ 
    return (new ListIterator()); 
} 

public static void main(String[] args) 
{ 
    Deque<Integer> deque = new Deque<Integer>(); 
    for(int i=0; i<5; i++) 
    { 
     deque.addFirst(i); 
     deque.addLast(9-i); 
    } 

    for(Integer i : deque) 
    { 
     StdOut.println(i); 
    } 
} 

} 나는이 코드를 실행하면이 = 지난 first.next 할 시도 할 때

, 나는 NullPointerException이 수를 구현; 이유를 이해할 수는 있지만 목록을 위반하지 않고 해결하는 방법을 모르겠습니다. 어떤 해결책? 이중 연결된 형식 (즉, 이전 참조 노드를 모두 제거)을 사용하는 것이 불필요한가요?

답변

1

초기화되지 않은 변수에 대한 액세스를 피함으로써 NullPointerException을 피할 수 있습니다. 특정 예에서

는 생략 : 생성자에서

first.next = last; 
last.prev = first; 

을 방어 프로그램을 사용하고이 변수를 액세스하기 전에, 초기화되지 않은 수의 경우는 null을 확인합니다.당신의 addFirst 방법의 예를 들어

:

public void addFirst(Item item) 
{ 
    Node oldfirst; 
    if (first != null){ 
     oldfirst = first; 
    } 

    first = new Node(); 
    first.item = item; 

    if (oldfirst != null){ 
     first.next = oldfirst; 
     oldfirst.prev = first; 
    } 
    size++; 
} 

그런데,이 학습 운동인가? 그렇지 않다면 Java 라이브러리는 링크 목록을 포함하여 Deques를 사용할 준비가되었습니다. http://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html

+0

감사합니다. 그리고 네, 이것은 주어진 라이브러리 밖에서 라이브러리를 사용할 수 없다고 엄격히 결정한 과제입니다. –

1

크기는 2부터 어떻게됩니까? Item을 추가 할 때까지 0이어야합니다.

초기 조건은 prevnext이 모두 null이어야합니다. 단일 항목을 추가 할 때 크기는 1이어야하고 prevnext이 모두 해당 개체를 가리켜 야합니다.

1

Deque가 비어 있으면 "다음"및 "이전"이 없습니다. 그것은 완전히 비어 있습니다. 데이터가있는 경우에만 "다음"과 "이전"이 있습니다.

따라서 Deque를 초기화 할 때 prevnextnull 참조에 할당하지 마십시오. 그들이 null이라는 사실은 그곳에 아무 것도 없다는 것을 나타내며, 물론 이전이나 이후에 오는 것이 없습니다.

물론 크기는 0이어야합니다.

그런 다음 addFirstaddLast 방법으로, 당신은 당신의 firstlast가 null 인 경우를 처리해야합니다. 이 경우 모두 동일한 값으로 초기화해야합니다. 여기서 nextprev은 모두 null입니다. 크기를 1로 설정하십시오.

first 또는 last의 항목이 각각 null 인 경우에만 (항목 추가, 연결 수정) 진행하십시오.

귀하의 removeFirstremoveLast 방법에서도 null을 확인하십시오.

짧은 버전 : 빈 목록의 경우가 특별합니다. 빈 목록으로 시작해야합니다. addremove 방법에서이 특별한 경우를 확인해야합니다.