Traverse every unique path (from root to leaf) in an arbitrary tree structure

前端 未结 4 1247
执念已碎
执念已碎 2021-01-31 12:18

I have several lists:

A = [\"a0\", \"a1\"]       // the number of lists varies
B = [\"b0\", \"b1\", \"b2\"] // such as the number of elements in a list.
C = [\"c         


        
相关标签:
4条回答
  • 2021-01-31 13:03

    So basically you are doing a depth first search, but rather than tracking the visiting of the nodes explicitly in a non-destructive way, or maintaining enough context to search without tracking, you are destroying the tree to do this tracking.

    The traditional way to convert this to a plain DFS would be to loop around your recursion condition, basically change the child recursive call to something like:

    } else {
      for (Node child = node.firstChild(); node != null; node = node.nextChild()) {
          traverse(child);
      }
    }
    

    This will traverse all your children, and you can pretty much remove the node.isLeaf case, since backtracking is done automatically for you. Note that I made up the nextChild function since I can't see what it's called in your code, but you must have something similar, or some way to iterate through the children.

    An alternate way that preserves more of the structure of your existing code would be to maintain a separate data structure which contains a set of "visited" nodes, this could be as simple as a Set of strings if all your node names are unique - rather than delete the node, add it to the "visited" set, and in your recursion condition, don't check for null, but rather find the first unvisited node. This is probably more complicated than the suggestion above, but might be more similar to what you have now - and would avoid loops in the case you ever need to do this on a cyclic graph rather than a tree.

    0 讨论(0)
  • 2021-01-31 13:07

    1,Find leaf node
    2,Up traversal from leaf node

    public void printPath(N n) {
            if (n == null)
                return;
            if (n.left == null && n.right == null) {
                do {
                    System.out.print(n.value);
                    System.out.print(" ");
                } while ((n = n.parent) != null);
                System.out.println("");
                return;
            }
            printPath(n.left);
            printPath(n.right);
        }
    

    printPath(Root);

    0 讨论(0)
  • 2021-01-31 13:13

    Something that I came up with working on printing the words in a TrieTree that can be easily adaptable to other kinds of trees or different needs:

    public void rootToLeaves() {
        HashMap<Integer, TrieNode> hashMap = new HashMap<Integer, TrieNode>();
        for(TrieNode trieNode : root.getChildren())
            rootToLeaves(trieNode, hashMap, 0);
    }
    
    private void rootToLeaves( TrieNode trieNode, HashMap<Integer, TrieNode> hashMap, int heightIndex ) {
        hashMap.put(heightIndex, trieNode);
    
        if( trieNode.isLeaf() )
            printValues(hashMap, heightIndex);
        else
            for( TrieNode childNode : trieNode.getChildren() )
                rootToLeaves( childNode, hashMap, heightIndex + 1 );
    }
    
    private void printValues(HashMap<Integer, TrieNode> hashMap, int heightIndex) {
        for(int index = 0; index <= heightIndex; index++)
            System.out.print(hashMap.get(index).getValue());
        System.out.println();
    }
    

    This solution does a nice job in terms of memory management (It uses a single HashMap whose size will never exceed the height of the tree) and it offers a lot of flexibility (Just replace printValues with whatever you need).

    NOTE: Knowing the height of the tree in advance will let you use a simple Array instead of a Map.

    0 讨论(0)
  • 2021-01-31 13:18

    OK. I think you actually mean that you want to find every path from root to a leaf.

    Then (a un-optimized version)

    void traverse (Node root) {
      // assume root != NULL
      traverse (root, new LinkedList<Node>());
    }
    
    private void traverse (Node root, LinkedList<Node> path) {
      path.add(root);
      if (root.isLeaf()) {
        print path;
      }
      else {
        for each node of root {
          traverse (node, new LinkedList<Node>(path));
        }
      }
    }
    
    0 讨论(0)
提交回复
热议问题