2011-07-19 53 views
5

我有表示为Set<Integer>[]获取路径

树以下Set<Integer>[]

[ { 1 }, { 2, 3 }, { 4 }, { 5, 6, 7 } ] 

表示为以下三种:

 1 
    /\ 
    / \ 
/ \ 
    2  3 
    |  | 
    4  4 
/|\  /|\ 
5 6 7 5 6 7 

所以树中的每个级别编码为Set。树中特定级别的所有孩子都是一样的。第一组中可以有多个整数。

我想,从Set<Integer>[],所有的路径从根到叶的列表:

[ [ 1, 2, 4, 5 ], [ 1, 2, 4, 6 ], [ 1, 2, 4, 7 ], [ 1, 3, 4, 5 ], [ 1, 3, 4, 6 ], [ 1, 3, 4, 7 ] ] 
+0

只是为了阐明,是表示为一组数组还是一组数组?我有点困惑。 – Sam

+0

@Wesam:问题陈述:'设置 []',所以这是一个'Set '的数组。 – Jasper

回答

4

在树搜索的关键是平时执行一个好的Ajacency函数,它为相邻节点提供特定的节点。

对于这棵树,邻接函数会希望找到该节点位于哪一层,然后将下一层的节点作为邻接返回。它看起来像这样:

/** 
    * This returns the adjacent nodes to an integer node in the tree 
    * @param node 
    * @return a set of adjacent nodes, and null otherwise 
    */ 
    public Set<Integer> getAdjacentsToNode(Integer node) { 

    for (int i = 0; i < tree.size(); i++) { 
     Set<Integer> level = tree.get(i); 
     if (level.contains(node) && i < tree.size() - 1) { 
     return tree.get(i + 1); 
     } 
    } 
    return null; 
    } 

假设我们已经在类中定义了一个字段的树。

在我们运行搜索之前,我们想要适当地设置根目录并对路径做一些预处理。因此,我们做到以下几点:

/** 
* initializes our search, sets the root and adds it to the path 
*/ 
    public void initialize() { 
    root = -1; 
    for (Integer node : tree.get(0)) { 
     root = node; 
    } 
    currentPath.add(root); 
    } 

假设currentPathroot已经被定义为字段。

然后,我们运行树上追加每个节点我们目前的道路,因为我们遍历树,并添加这条道路给我们设定的路径和正在重置它,当我们到达一个死胡同(枫叶)一个DFS搜索:

/** 
    * runs a DFS on the tree to retrieve all paths 
    * @param tree 
    */ 
    public void runDFS(Integer node) { 
    if (getAdjacentsToNode(node) != null) { 
     for (Integer adjNode : getAdjacentsToNode(node)) { 
     currentPath.add(adjNode); 
     runDFS(adjNode); 
     } 
     currentPath.remove(currentPath.size() -1); 
    } else { 
     paths.add(currentPath.toArray(new Integer[0])); 
     currentPath.remove(currentPath.size() -1); 
    } 
    } 

全班,因此,看起来是这样的:

import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.HashSet; 
import java.util.List; 
import java.util.Set; 

public class DFS { 
    private List<Integer> currentPath = new ArrayList<Integer>(); 
    private List<Integer[]> paths = new ArrayList<Integer[]>(); 
    private ArrayList<Set<Integer>> tree; 
    private Integer root; 
    /** 
    * constructor 
    * @param tree 
    */ 
    public DFS(ArrayList<Set<Integer>> tree) { 
    this.tree = tree; 
    } 

    public List<Integer[]> getPaths() { 
    return paths; 
    } 
    public void setPaths(List<Integer[]> paths) { 
    this.paths = paths; 
    } 
    public Integer getRoot() { 
    return root; 
    } 
    public void setRoot(Integer root) { 
    this.root = root; 
    } 

/** 
* initializes our search, sets the root and adds it to the path 
*/ 
    public void initialize() { 
    root = -1; 
    for (Integer node : tree.get(0)) { 
     root = node; 
    } 
    currentPath.add(root); 
    } 

    /** 
    * This returns the adjacent nodes to an integer node in the tree 
    * @param node 
    * @return a set of adjacent nodes, and null otherwise 
    */ 
    public Set<Integer> getAdjacentsToNode(Integer node) { 

    for (int i = 0; i < tree.size(); i++) { 
     Set<Integer> level = tree.get(i); 
     if (level.contains(node) && i < tree.size() - 1) { 
     return tree.get(i + 1); 
     } 
    } 
    return null; 
    } 

    /** 
    * runs a DFS on the tree to retrieve all paths 
    * @param tree 
    */ 
    public void runDFS(Integer node) { 
    if (getAdjacentsToNode(node) != null) { 
     for (Integer adjNode : getAdjacentsToNode(node)) { 
     currentPath.add(adjNode); 
     runDFS(adjNode); 
     } 
     currentPath.remove(currentPath.size() -1); 
    } else { 
     paths.add(currentPath.toArray(new Integer[0])); 
     currentPath.remove(currentPath.size() -1); 
    } 
    } 
} 

为了测试它,我们试试这个:

public static void main(String[] args) { 
    ArrayList<Set<Integer>> tree = new ArrayList<Set<Integer>>(); 
    Set<Integer> level1 = new HashSet<Integer>(); 
    level1.add(new Integer(1)); 

    Set<Integer> level2 = new HashSet<Integer>(); 
    level2.add(new Integer(2)); 
    level2.add(new Integer(3)); 

    Set<Integer> level3 = new HashSet<Integer>(); 
    level3.add(new Integer(4)); 

    Set<Integer> level4 = new HashSet<Integer>(); 
    level4.add(new Integer(5)); 
    level4.add(new Integer(6)); 
    level4.add(new Integer(7)); 

    tree.add(level1); 
    tree.add(level2); 
    tree.add(level3); 
    tree.add(level4); 

    DFS dfsSearch = new DFS(tree); 
    dfsSearch.initialize(); 
    dfsSearch.runDFS(dfsSearch.getRoot()); 

    for (Integer[] path : dfsSearch.getPaths()) { 
     System.out.println(Arrays.toString(path)); 
    } 

我们得到以下输出:

[1, 2, 4, 5] 
[1, 2, 4, 6] 
[1, 2, 4, 7] 
[1, 3, 4, 5] 
[1, 3, 4, 6] 
[1, 3, 4, 7] 
0

我不会写代码,但最简单的方法将是一个深度优先遍历,在每个级别你将每个条目附加到当前路径。另外,您的返回值将是列表的集合(或数组),因为垂直路径不能是无序集合。

def getPaths(levels) { 
    return getPaths(levels, 0, new Set()) 
} 

def getPaths(levels, currentIndex, paths) { 

    if(currentIndex == levels.length) 
    return paths 

    def newPaths = new Set(paths) 

    for(path : paths) { 
    for(level : levels) { 
     newPaths.add(path + level) 
    } 
    } 

    return getPaths(levels, currentIndex + 1, newPaths) 

} 
0

尝试是这样的:

伪代码

public static List<Integer[]> getAllPaths(Set<Integer>[] tree){ 

    // Get the overall number of path 
    int totalSize = 1; 
    for(Set<Integer> line : tree){ 
     totalSize *= line.size(); 
    } 

    // Create the empty paths 
    List<Integer[]> allPaths = new ArrayList<Integer[]>(totalSize); 
    for(int i = 0 ; i<totalSize ; ++i){ 
     Integer[] path = new Integer[tree.length]; 
     allPaths.add(path); 
    } 

    // Fill the paths 
    int indexLine = 0; 
    for (Set<Integer> line : tree) { 
     Iterator<Integer[]> pathIterator = allPaths.iterator(); 
     Iterator<Integer> lineIterator = line.iterator(); 
     while(pathIterator.hasNext()){ 
      if(!lineIterator.hasNext()){ 
       lineIterator = line.iterator(); 
      } 
      pathIterator.next()[indexLine] = lineIterator.next(); 
     } 
     ++indexLine; 
    } 
    return allPaths; 
} 

它适用于你的例子:

public static void main(String[] args) { 

    Set<Integer> line1 = new HashSet<Integer>(); 
    line1.add(new Integer(1)); 
    Set<Integer> line2 = new HashSet<Integer>(); 
    line2.add(new Integer(2)); 
    line2.add(new Integer(3)); 
    Set<Integer> line3 = new HashSet<Integer>(); 
    line3.add(new Integer(4)); 
    Set<Integer> line4 = new HashSet<Integer>(); 
    line4.add(new Integer(5)); 
    line4.add(new Integer(6)); 
    line4.add(new Integer(7)); 

    Set[] test = {line1, line2,line3,line4}; 

    List<Integer[]> allPaths = getAllPaths(test); 

    for(Integer[] path : allPaths){ 
     System.out.println(Arrays.toString(path)); 
    } 
}