2015-07-12 73 views
0

我在寫一個維護Deque的類(也就是說它可以添加到LinkedList的頭部或尾部)。我創建了一個使用主類的測試,該類將一個項目添加到頭部,另一個添加到尾部,並且它看起來存在,因爲size = 2並且打印,但是我添加的實際字符串不會打印。爲什麼?迭代器不打印明確存在的項目LinkedList

這是我的代碼:

import java.util.Iterator; 
import java.util.NoSuchElementException; 


/** 
* 
* @author David Farthing 
*/ 
public class Deque<Item> implements Iterable<Item> { 
    //fields for Deque class 
    private LinkedList deque; 
    private int numNodes; 

    //constructor 
    public Deque(){ 
     deque = new LinkedList(); 
     numNodes = 0; 
    } 

     private class DequeIterator implements Iterator<Item> { 
     private Node<Item> curr; 
     public DequeIterator(Node<Item> head) { 
      curr = head; 
     } 
     @Override 
     public boolean hasNext(){return curr != null;} 
     @Override 
     public void remove(){ throw new UnsupportedOperationException();} 

     @Override 
     public Item next() { 
      if(!hasNext()) throw new NoSuchElementException(); 
      Item item = curr.data; 
      curr = curr.next; 
      return item; 
     } 
    } //end DequeIterator 

     //inner class to implement a doubly linked list for the deque 
    private class LinkedList { 
     Node head; 
     Node tail; 

     private LinkedList(){ 
      head = null; 
      tail = null; 
     } 
     private Node getHead(){ 
      return head; 
     } 
     private Node getTail(){ 
      return tail; 
     } 
    }//end inner class Linked List 

    //inner class to implement a Node for the LinkedList 
    private class Node<Item>{ 
     private Item data; 
     private Node<Item> next; //connection to the next node in the list 
     private Node<Item> prev; //connection to the previous node in the list 


     private Node(Item data){ 
      this.data = data; 
      next = null; 
      prev = null; 
     } 

     private Item getData(){ 
      return data; 
     } 
     private Node getNext(){ 
      return next; 
     } 
     private Node getPrev(){ 
      return prev; 
     } 
    }//end inner class Node 

    //add item to end 
    public void addLast(Item item){ 
     Node h = deque.getHead(); 
     Node t = deque.getTail(); 
     //if list is empty 
     if(h==null && t==null){ 
      h = new Node(item); 
      t = new Node(item); 
      h.next = t; 
      t.prev = h; 
     } 
     //if there is only one item in list 
     else if(h==t){ 
      t = new Node(item); 
      t.prev = h; 
      h.next = t; 
     } 
     else { 
     //get the node previous to tail 
     Node oldLast = t.getPrev(); 
     Node newLastNode = new Node(item); 
     newLastNode.next = t; //the new last node is pointing to tail 
     oldLast.next = newLastNode; //the previous last node which temp is 
           //pointing to now points to new last node 
     } 
     numNodes++; 
    } 

    //remove and return item from front 
    public Item removeFirst(){ 
     Node h = deque.getHead(); 
     //get Item data from first node in list; uses convert to turn Object 
     //data into Item data 
     Item first = convert(h.next.getData()); 
     Node second = h.next.next; //second item in list 
     h.next = second;   //head now points to second item 
     second.prev = h;   //second item points back to head 
     numNodes--; 
     return first; 
    } 

    //remove and return item from end 
    public Item removeLast(){ 
     //get the node previous to tail 
     Node lastNode = deque.getTail().prev; 
     //get the data from the last node; uses convert to turn Object into Item 
     Item last = convert(lastNode.getData());  
     Node t = deque.getTail();//get the tail itself 
     t.prev = lastNode.prev;    //make the tail point back to the 
              //node previous to the last 
     numNodes--;       //decrement the number of nodes 
     return last; 
    } 

    //return an Iterator over the items from front to end 
    @Override 
    public Iterator<Item> iterator(){ 
     Node h = deque.getHead(); 
     return new DequeIterator(h); 
    } 

    //convert any object to Item type 
    private Item convert(Object o){ 
     return (Item) o; 
    } 

    //is the Deque empty 
    public boolean isEmpty(){ 
     if(numNodes == 0) return true; 
     else return false; 
    } 

    //return the number of items in Deuque 
    public int size(){ 
     return numNodes; 
    } 

    //add item to front 
    public void addFirst(Item item){ 
     Node h = deque.getHead(); 
     if(h == null) { 
      h = new Node(item); 
      Node t = deque.getTail(); 
      t = new Node(item); 
      h.next = t; 
      t.prev = h; 
      numNodes++; 
     } 
     else { 
      Node temp = new Node(item); //create new node containing item 
      temp.next = h.next;   //have temp point to the successor to 
             //head 
      h.next.prev = temp;   //prev of first item now points to temp 
      h.next = temp;    //successor of head is now the new node 
      temp.prev = h;    //the previous pointer now points to h   
      numNodes++; 
     } 
    } 




    //unit test 
    public static void main(String[] args){ 
     Deque myList = new Deque(); 
     String f = "first"; 
     String l = "last";   
     myList.addFirst(f); 
     myList.addLast(l); 
     Iterator itr = myList.iterator(); 
     while(itr.hasNext()) { 
      StdOut.print(itr.next() + " "); 
     } 
     StdOut.println("Number of nodes: " + myList.size()); 
    }// end main 


}//end class Deque 

打印雙端隊列(鏈表)的輸出是:

運行: 節點數目:2

問:爲什麼沒有while循環中的迭代器打印字符串「first」和「last」?

+0

我評論了所有使用hasNext()方法,名爲next(),並且我得到了NullPointerException。可能你在Deque實現中有一些錯誤。祝你好運! – Zano

回答

1

它不起作用的原因是你實際上沒有在你的列表中放入任何東西。

當調用addFirst時,它不會設置deque.headdeque.tail。 該版本將工作:

public void addFirst(Item item){ 
    Node h = deque.getHead(); 
    if(h == null) { 
     h = new Node(item); 
     Node t = deque.getTail(); 
     t = new Node(item); 
     h.next = t; 
     t.prev = h; 
     numNodes++; 
     deque.head = h; 
     deque.tail = t; 
    } 

但我質疑是否有必要實現自己的Deque。這是一些測試練習嗎? JDK包括java.util.LinkedList這是一個Deque。

+0

是的,我想在使用java實現之前自己學習數據結構。它是課程的一部分。感謝您的幫助。這讓我瘋狂。你的回答非常幫助我,並且工作。另外我明白我做錯了什麼,這是最重要的部分。 –

+0

很高興爲您提供幫助。它看起來像處理java變量,就好像它們是通過引用傳遞一樣。他們是傳遞價值! 'deque.head'爲空意味着它指向無處,'null',並且你*拷貝*(傳值)引用變量'h'。但它只是一個副本 - 當你改變'h'時,你不會改變'deque.head'。 –