Haskell中展平含子树列表的排列树:实现方法求助
展平排列树的解决方案
首先,我得先明确一下你可能使用的树结构——因为你没给出Tree的具体定义,这里我假设是多叉树(毕竟排列的分支通常不止两个),常见的定义如下:
data Tree a = Node a [Tree a] deriving (Show, Eq)
比如,对于字符串"ab",你的permute函数生成的树可能长这样:
-- 或者如果包含所有排列的顶层结构,可能是: Node '' [Node 'a' [Node 'b' []], Node 'b' [Node 'a' []]]
不管是哪种情况,展平排列树的核心逻辑都是收集所有从根到叶子的路径——因为每一条路径正好对应一个完整的排列。下面是对应的实现:
基础版本(针对叶子节点是单个字符的树)
flattenPermTree :: Tree Char -> [String] -- 叶子节点:只有当前字符,返回单元素列表 flattenPermTree (Node c []) = [[c]] -- 非叶子节点:把当前字符加到每个子树路径的开头,再合并所有子树的结果 flattenPermTree (Node c children) = map (c :) $ concatMap flattenPermTree children
处理带顶层空节点的情况
如果你的permute函数生成的树顶层是一个空节点(用来包含所有排列分支),可以稍微调整一下:
flattenPermTree :: Tree Char -> [String] flattenPermTree (Node '' children) = concatMap flattenPermTree children flattenPermTree (Node c []) = [[c]] flattenPermTree (Node c children) = map (c :) $ concatMap flattenPermTree children
示例测试
假设permute "ab"生成的树是Node '' [Node 'a' [Node 'b' []], Node 'b' [Node 'a' []]],调用flattenPermTree会得到:
["ab", "ba"]
逻辑解释
这个函数的思路很直观:
- 遇到叶子节点(没有子节点),就把当前字符包装成单字符字符串的列表;
- 遇到非叶子节点,先递归展平所有子树,得到子树对应的所有排列字符串,再把当前节点的字符加到每个字符串的最前面,最后把所有子树的结果合并起来。
如果你的Tree定义是二叉树(比如data Tree a = Empty | Node a (Tree a) (Tree a)),那只需要把处理子节点的逻辑改成遍历左右子树即可,核心思路还是收集根到叶子的路径:
flattenPermTree :: Tree Char -> [String] flattenPermTree Empty = [] flattenPermTree (Node c Empty Empty) = [[c]] flattenPermTree (Node c left right) = map (c :) (flattenPermTree left ++ flattenPermTree right)
内容的提问来源于stack exchange,提问作者homior
相关产品推荐
相关产品推荐

