【问题标题】:Descending ListNode Iterator Implementation降序 ListNode 迭代器实现
【发布时间】:2016-01-11 16:58:48
【问题描述】:

我在此方法中的目标是编写一个迭代器的实现,该迭代器按降序遍历 listNode 的元素。 (从后到前)我附上了我的升序迭代器的实现。任何正确方向的帮助将不胜感激。

 public MyDescendingDequeIterator(ListNode<E> back, ListNode<E> front) {                    
  frontOfList = front;
  nextToReturn = back;
   while (nextToReturn.next != null) {
    nextToReturn = nextToReturn.next;
}          
}


public boolean hasNext() {
 if (nextToReturn == null){
 return false;
 } else {
 ListNode<E> current = frontOfList;
 return true;
 }
}

public E next() {
ListNode<E> current = frontOfList;
while ( current.next != nextToReturn ) {
  current = current.next;
}
nextToReturn = current;

return nextToReturn.data;

}
public void remove() {
    throw new UnsupportedOperationException();
}

}

【问题讨论】:

    标签: java linked-list deque


    【解决方案1】:

    如果它是一个只有 next() 方法的常规 ListNode 实现,您将需要实现 prev() 方法 - 在这种情况下,hasNext 与您已经实现的非常相似。

    另一种方法是保持列表的开头并每次迭代,直到下一个元素成为 nextToReturn(然后更新 nextToReturn)。这是不太理想的方法,因为您需要从长度为 m 的列表的末尾迭代 O(m^2);

    更新:

    好的,首先你不需要元素的数量,因为它与迭代器的想法完全相反。

    假设我们有

    public MyDescendingDequeIterator(ListNode<E> back, ListNode<E> front) {                    
      frontOfList = front;
      nextToReturn = frontOfList;
      current = frontOfList;
    }
    

    接下来要做的是设置nextToReturn = back(现在你根本不使用back)。而且您实际上并不需要两个变量,因为 nextToReturn 是当前迭代器。

    所以它转换为:

    public MyDescendingDequeIterator(ListNode<E> back, ListNode<E> front) {                    
          frontOfList = front;
          nextToReturn = back;
        }
    

    现在让我们看看next()方法

    正如我所说,您在这里不需要索引 for,因为您的 frontOfList 具有 next 属性。

    可能是这样的:

    public E next() {
        ListNode<E> current = frontOfList;
        while ( current.next != nextToReturn ) {
          current = current.next;
        }
        nextToReturn = current;
    
        return nextToReturn.data;
    
    }
    

    hasNext 的实现应该从这里简单明了。请注意,根据良好的编码标准,以ishas 开头的方法很少改变对象的状态。

    请注意,我在这里也省略了可能的空检查和其他可能的特定检查,这只是方向的一个示例。

    更新 2:

    现在想起来,构造函数中的第二个参数也不需要,就是这样:

    public MyDescendingDequeIterator(ListNode<E> front) {                    
        frontOfList = front;      
        nextToReturn = front;
    
        // calculate back here instead of get it as param
        while ( nextToReturn.next != null) {
            nextToReturn = nextToReturn.next;
        }          
    }
    

    更新 3:

    看,仅仅开始编写一些代码并期望它能够工作是没有帮助的,你应该先坐下来,开始在纸上画出带有箭头的方框,然后试着理解每个函数应该做什么.

    正如我之前所说,您的hasNext() 方法有一个错误并且通常不正确。为什么要检查null?你从后到前移动,你在前面的某个地方有一个空值吗?你需要current 对象做什么。它有什么作用?

    next() 方法还应该检查您是否已经在第一个元素处。否则它将(并且确实)在最后一个元素处导致 NullPointerException。

    尝试先调试,或者至少添加一些打印输出,这有助于了解错误在哪里。但首先你应该构建算法,然后才开始编码,反之亦然。

    【讨论】:

    • 我知道我可以遍历列表的开头,直到我收到索引的元素比上一次迭代的值小一。我只是不知道如何访问我在另一个类“front”中声明的私有字段,该类包含 LinkedList 前面的节点
    • 在MyDescendingDequeIterator中添加一个方法setFront,例如在创建后调用?
    • 或者改变一个构造函数来获得两个参数,前后 - 这实际上是相同的,但少了几行。
    • 我可以在下面的标题中为前面的元素添加一个参数吗? public MyDescendingDequeIterator(ListNode&lt;E&gt; back)
    • 是的,这是构造函数。只需将其添加为第二个参数即可。
    猜你喜欢
    • 1970-01-01
    • 2018-11-17
    • 2016-03-24
    • 2020-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-23
    • 2012-01-22
    相关资源
    最近更新 更多