2015-07-12 26 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'。 –