2011-07-19 189 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)); 
    } 
}