【问题标题】:Java Tree Struct & Breadth-first-searchJava 树结构和广度优先搜索
【发布时间】:2012-02-08 22:26:59
【问题描述】:

我基于根节点创建了一个简单的参数化树结构。每个节点都拥有一个包含其子注释的数组列表和一个到其父节点的链接。很简单。

现在是我无法解决的问题(在不久的将来):

我想在这棵树上写一个广度优先搜索。我想在(实现的)迭代器接口的帮助下实现这个特性。但我真的无法让它发挥作用: 问题是也可迭代的列表结构。我不知道如何实现 hasNext()、next() 和 remove() 函数:/

你有什么想法吗?

问候

代码:

public class Tree<T> implements Iterator<T>{

private Node<T> root;

/**
 * Default constructor.
 */
public Tree() {
    super();        
}

/**
 * Return the root Node of the tree.
 * @return the root element.
 */    
public Node<T> getRoot() {
    return this.root;
}

/**
 * Set the root Element for the tree.
 * @param Root the root element to set.
 */
public void setRoot(Node<T> Root) {
    this.root = Root;
}
...

公共类节点{

public List<Node<T>> children;
public Node<T> parent;
public T data;

/**
 * Default constructor.
 */
public Node() {
    super();
}

/**
 * Create a Node<T> with an instance of T.
 * @param data an instance of T.
 */
public Node(T nodeData) {
    this();
    setData(nodeData);        
}

/**
 * Create a Node<T> with an instance of T.
 * @param data an instance of T.
 */
public Node(T nodeData, Node<T> parentNode) {
    this();       

    setData(nodeData);
    setParent(parentNode); 

}
...   

【问题讨论】:

  • 树不应该实现Iterator&lt;T&gt;,它应该实现Iterable&lt;T&gt;。那么迭代器应该是一个单独的类,它的一个实例由Iterable.iterator() 方法返回。

标签: java


【解决方案1】:

您的iterator() 方法将创建一个Iterator&lt;Node&lt;T&gt;&gt;,它将使用仅包含根的Queue&lt;Node&lt;T&gt;&gt; 进行初始化。

Iterator.next() 将从堆栈中取出第一个元素,将其所有子元素插入堆栈并返回。 [别忘了把它也弹出来]

Iterator.remove() 将从其父级children 列表中删除最后一个元素[您可以使用parent 字段访问父级。

还请注意,在语法上,您应该实现 Iterable&lt;T&gt; 而不是 Iterator&lt;T&gt;。您将创建的迭代器 [如上所述] 将实现 Iterator&lt;T&gt;

【讨论】:

  • 在移除节点后,迭代器可能希望从队列中移除其子节点。但是您不能从队列末尾删除元素。您要么必须将 Queue 更改为 Deque,要么使用第二个 Queue 来记住您必须忽略哪些节点。
【解决方案2】:

您的Node 类需要实现Iterable 接口,而不是“迭代器”接口。

Iterable 接口本质上说“这个类可以返回一个迭代器并被迭代”,而Iterator 接口说“我可以迭代某些东西并返回那些项目”。 Iterable 接口需要实现 Iterator 才能工作。

这是一个快速的、人为的示例(未经测试,但您应该了解要点)。

public class MyList implements Iterable<Integer> {

    public List<Integer> x;

    public Iterator<Integer> iterator() {
        return new MyListIterator(this);
    }

}

下面是该类的简单迭代器:

public class MyListIterator implements Iterator<Integer> {

    private List<Integer> list;
    private int index;

    public MyListIterator(MyList list) {
        this.list = list;
        this.index = 0;
    }

    public boolean hasNext() {
        return this.index < this.list.x.size()
    }

    public Integer next() {
       Integer i = this.list.x.get(this.index);
       this.index += 1;
       return i;
    }

    public void remove() {
      //Not implemented
    }

}

它可以帮助您了解如何显式使用迭代器:

MyList list = new MyList();
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

【讨论】:

  • 首先,非常感谢您的快速反馈和解释!在我的实现中,通过节点而不是树实现可迭代不是更好吗?我有点迷茫……
  • 是的,当然。此示例旨在展示这些接口如何协同工作,而不是您应该如何自己实现它们。 @amit 在Iterator 中描述了您需要的算法。
猜你喜欢
  • 1970-01-01
  • 2011-01-31
  • 1970-01-01
  • 1970-01-01
  • 2016-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多