循环链表的Java迭代器

时间:2014-03-05 22:04:35

标签: java iterator circular-list josephus

我创建了一个CircularLinkedList类,而不是使用util LinkedList类。问题基于Josephus problem,指出对于一个20人的圈子,每个第12个人将被杀死,直到确定幸存者将留在哪个位置(使用迭代器)。我很困惑如何使用Iterator来解决这个问题,因为我使用自己的类而不是LinkedList,它已经有了一个iterator()方法,所以我可以像这样声明一个Iterator:

Iterator<E> iter = cll.iterator();

我不知道如何编写自己的Iterator方法,我觉得我必须过度思考这个问题。任何帮助表示赞赏!我可以发布我的代码,如果它可以清除我忘记提及的任何内容

我仍然坚持这一点,所以我想我会发布我的代码,看看是否有人可以提供帮助。这很多,所以我道歉。

Itr类(Iterator)

import java.util.Iterator;

public class Itr<E> extends CircularLinkedList<E> implements Iterator<E>
{

  /** the size of the list */
  private int size = 0;
  /** for the hasNext() method for Iterator */
  private int nextNode = 0;
  /** two Nodes used for next() method for Iterator */
  private Node<E> lastReturned = null;
  private Node<E> nextUp;

  /** part of the Iterator implementation */
  public boolean hasNext()
  {
    return nextNode < size;
  }

  /** part of the Iterator implementation */
  public E next()
  {
    lastReturned = nextUp;
    nextUp = nextUp.getNext();
    nextNode++;
    return lastReturned.data;
  }

  /** part of the Iterator implementation */
  public void remove()
  {
    Node<E> lastNext = lastReturned.getNext();
    if (lastReturned == null)
      nextUp = lastNext;
    else
      nextNode--;
    lastReturned = null;    
  }
}

约瑟夫斯班

public class Josephus<E>
{
  public static void main(String[] args)
  {
      CircularLinkedList cll = new CircularLinkedList();
      Itr iter = cll.iterator();

      int lastMan = 0;
      int n = 20;
      int passes = 12;
        while(n > 1)
        {
          iter.next();

          for(int i = 0; i < n; i += passes)
          {
          iter.hasNext();
          iter.remove();
          if(n == 1)
            lastMan = n;
          }
        }  
    System.out.println("Survior: " + lastMan);
  }
}

CircularLinkedList类

public class CircularLinkedList<E> 
{
  public class Node<E>
  {
    /* data value **/
    public E data;
    /* the link **/
    private Node<E> next = null;

    /** constructs a Node with given data and link
      * @param data the data value
      * @param next the link
      */
    public Node(E data, Node<E> next)
    {
      this.data = data;
      this.next = next;
    }

    /** construct a Node with given data value
      * @param data the data value
      */
    public Node(E data)
    {
      this.data = data;
    }

    /** return the data value of a Node
      * @return the data value
      */
    public E getData()
    {
      return data;
    } 

    /** set the next Node in a list
      * @param append the data value that the new Node will contain
      */
    public void setNext(Node append)
    {
      next = append;
    }

    /** return the next Node
      * @ return the next Node
      */
    public Node<E> getNext()
    {
      if(current.next == null)
      current.next = current;

      return next;
    }
  }

  /** a reference into the list */
  private Node<E> current = null;
  /** the size of the list */
  private int size = 0;

  /** helper methods */

  /** remove the first occurance of element item.
    * @param item the item to be removed
    * @return true if item is found and removed; otherwise, return false.
    */
  public void removeItem(E item)
  {
    Node<E> position = current;
    Node<E> nextPosition1,
            nextPosition2;

    while (position.next != null)
    {
      if(position.getNext().getData().equals(item))
      {
        nextPosition1 = position.getNext();
        nextPosition2 = nextPosition1.getNext();
        position.setNext(nextPosition2);
      } 
      else
      {
        position = position.getNext();  
      }
    }
  }

  /** set the first Node in a list
    * @param append the data value that the new Node will contain
    */
  public void addFirst(E append)
  {
    current = new Node<E>(append, current);
    size++;
  }

  /** add a new Node as the last in the List
    * @param data value of the new Node
    */
  public void addNext(E value)
  {
    // location for new value
    Node<E> temp = new Node<E>(value,null);
    if (current != null)
    {
      // pointer to possible tail
      Node<E> finger = current;
      while (finger.next != null)
      {
        finger = finger.next;
      }
      finger.setNext(temp);
    } else current = temp;
    size++;
  }

  /** return the data value of the fourth Node in the list
    * @return the data value
    */
  public E printFourth()
  {
    current.next.next.next = current;
    return current.next.next.next.getData();
  }

  /** return the size of the LinkedList
    * @return the size
    */
  public int size()
  {
    return size;
  }

  public E get(int index)
  {    
    Node<E> temp = null;
    for(int i = 0; i < index; i++)
    {
      temp = current.next;
      System.out.print(temp.getData() + " ");

    }
    return temp.getData();
  } 

  public Itr<E> iterator()
  {
    return new Itr<E>();
  }

  @Override
  public String toString()
  {
    StringBuilder sb = new StringBuilder();
    sb.append("[");
    Node<E> aux = this.current;
    boolean isFirst = true;
    while(aux != null)
    {
      if(!isFirst)
      {
        sb.append(", ");
      }
      isFirst = false;
      sb.append(aux.data.toString());
      aux=aux.next;
    }
  return sb.append("]").toString();
  }
}

我从行中的Itr类的next()方法得到NullPointerException

nextUp = nextUp.getNext();

我在CircularLinkedList类中做错了,因为它实际上不是循环的,或者我的驱动程序/ Itr类有问题吗?我有点迷失在这一点上。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

创建一个实现Iterator的自定义类,并从CLL.iterator方法返回自定义迭代器

请参阅LinkedList#ListItr获取灵感 - 但考虑了此练习的Iterator方法(next,hasNext,remove)。一个真正的循环链表将简单地跟随下一个节点,并且没有结束 - 如果至少有一个元素,hasNext将始终返回true。如果你的CLL实现有一个“结束”,那么一定要在遇到它时“回到开始”。

此外,CLL类应符合Iterable,这意味着它具有iterator方法来获取迭代器。