2015-09-26 68 views
4

我的树/节点类:如何遍历一个N叉树

import java.util.ArrayList; 
import java.util.List; 

public class Node<T> { 
    private T data; 
    private List<Node<T>> children; 
    private Node<T> parent; 

    public Node(T data) { 
     this.data = data; 
     this.children = new ArrayList<Node<T>>(); 
    } 

    public Node(Node<T> node) { 
     this.data = (T) node.getData(); 
     children = new ArrayList<Node<T>>(); 
    } 

    public void addChild(Node<T> child) { 
     child.setParent(this); 
     children.add(child); 
    } 

    public T getData() { 
     return this.data; 
    } 

    public void setData(T data) { 
     this.data = data; 
    } 

    public Node<T> getParent() { 
     return this.parent; 
    } 

    public void setParent(Node<T> parent) { 
     this.parent = parent; 
    } 

    public List<Node<T>> getChildren() { 
     return this.children; 
    } 
} 

我知道如何遍历二叉树,但遍历n元似乎更棘手。

我该如何去遍历这棵树。我在遍历树时需要一个计数器来对树中的每个节点进行编号/计数。

然后在特定的计数下,我可以停止并返回该计数的节点(可能删除该子树或在该位置添加子树)。

回答

3

最简单的方法是实施这样一个访问者模式:

public interface Visitor<T> { 
    // returns true if visiting should be cancelled at this point 
    boolean accept(Node<T> node); 
} 

public class Node<T> { 
    ... 

    // returns true if visiting was cancelled 
    public boolean visit(Visitor<T> visitor) { 
     if(visitor.accept(this)) 
      return true; 
     for(Node<T> child : children) { 
      if(child.visit(visitor)) 
       return true; 
     } 
     return false; 
    } 
} 

现在你可以使用这样的:

treeRoot.visit(new Visitor<Type>() { 
    public boolean accept(Node<Type> node) { 
     System.out.println("Visiting node "+node); 
     return false; 
    } 
}); 

或者为特定的任务:

class CountVisitor<T> implements Visitor<T> { 
    int limit; 
    Node<T> node; 

    public CountVisitor(int limit) { 
     this.limit = limit; 
    } 

    public boolean accept(Node<T> node) { 
     if(--limit == 0) { 
      this.node = node; 
      return true; 
     } 
     return false; 
    } 

    public Node<T> getNode() { 
     return node; 
    } 
} 

CountVisitor<T> visitor = new CountVisitor<>(10); 
if(treeRoot.visit(visitor)) { 
    System.out.println("Node#10 is "+visitor.getNode()); 
} else { 
    System.out.println("Tree has less than 10 nodes"); 
} 
+0

访问者模式可能有点矫枉过正,因为我们在这里只处理一种节点。 – Henry