找到n-ary树的所有子树

时间:2015-10-12 12:31:39

标签: algorithm tree

我试图找到n-ary树的所有子树。只有BFS或DFS不起作用。因为树不是二进制的。例如:

        1
     /    \
    2      3
   / \    /|\
  4   6  5 7 8
        / \
       9   10

我想显示所有子树,包括这个

        1
     /    \
    2      3
     \     |
      6    7

如何从原始子树中提取该子树?

2 个答案:

答案 0 :(得分:2)

要生成给定树的所有(图论)子树,我需要一些辅助概念。

子树是树的连接子图,或者等效地,也是树的子图。

有根树的后代树是原始的有根树本身,或者是根树之一,它是其顶点之一的子节点。 (在这里给出一个确切的定义,因为从树的概念作为递归数据结构应该清楚)。

根树的根树根是与原始根树具有相同根的子树。我们可以通过计算根的(某些)直接子节​​点的根子树,并将它们与原始根相结合来获得根树的根节子树。

请注意,任意子树是后代树的有根子树。

为简单起见,我将处理非空树。

-- a (rooted) tree is a root node and a list of children attached to it
data Tree a = Node a [Tree a] deriving Show

获得后代是直截了当的:

-- a descendant tree  is either a tree itself, 
-- or a descendant of a child of its root
descendants :: Tree a -> [Tree a]
descendants t@(Node a ts) = t : concatMap descendants ts

生根的子树并不难:

-- to get a rooted subtree, take a root, choose which children to 
-- retain, take a rooted subtree of each retained child, 
-- and attach the results to a copy of the root

rootedSubtrees :: Tree a -> [Tree a]
rootedSubtrees (Node a ts) = [Node a tts | 
                              tts <- choices (map rootedSubtrees ts)]

-- this function receives a list of lists and generates all lists that 
-- contain 0 or 1 element from each input list
-- for ex. choices ["ab", "cd"] = ["","c","d","a","ac","ad","b","bc","bd"]
choices :: [[a]] -> [[a]]
choices [] = [[]]
choices (xs:xxs) = cs ++ [x:c | x <- xs, c <- cs] where cs = choices xxs

最后,任意子树列表是

subtrees :: Tree a -> [Tree a]
subtrees t = concatMap rootedSubtrees (descendants t)

答案 1 :(得分:0)

您可以执行以下操作。

  • 对于树中的每个顶点,您决定是否使用根顶点切割子树或继续探索。您的选择数量是~2 ^(节点数)。请注意,它恰好注意2 ^(节点数)(它少了但仍然是指数)因为在你剪切了一个子树之后你就不会去探索它。
  • 对于每个顶点的每个选项配置,使用DFS打印树。

您的示例是剪切了根458的子树的配置。

可以通过为每个节点设置标志来隐式地完成剪切。