1

解决方案 感谢 Karolis Juodelė,这是我对这个问题的优雅解决方案!谢谢 Karolis Juodelė :

prettyTree :: Show a=>BinTree a -> String
prettyTree Empty = ""
prettyTree (Node l x r) = prettyTree2((Node l x r),2)

prettyTree2 :: Show a=> (BinTree a, Int)-> String
prettyTree2 (Empty,_) = ""
prettyTree2 ((Node l x r),z) = prettyTree2(r,z+2) ++ replicate z ' ' ++ (show x) ++ ['\n'] ++ prettyTree2(l,z+2)

OLD 所以我想像这样打印一个二叉树:

putStr (prettyTree (Node (Node Empty 3 (Node Empty 7 Empty)) 8 (Node (Node Empty 8 Empty) 4 (Node Empty 3 Empty))))

      3
    4
      8
  8
      7
    3

我所拥有的是以下内容,仅将它们打印在两个不同的行中:

data BinTree a = Empty | Node (BinTree a) a (BinTree a) deriving (Eq)

prettyTree :: Show a => BinTree a -> String
prettyTree Empty = ""
prettyTree (Node l x r) = prettyTree l ++ middle ++ prettyTree r
    where
        maxHeight = max (treeHeight l) (treeHeight r) + 1
        middle = printSpace (maxHeight, maxHeight) ++ show x ++ "\n"

treeHeight :: BinTree a -> Integer
treeHeight Empty = 0
treeHeight (Node l x r) = 1 + max (treeHeight l) (treeHeight r)

printSpace :: (Integer,Integer) -> String
printSpace (0, _) = []
printSpace (_, 0) = []
printSpace (x, y) = "   " ++ printSpace ((x `mod` y), y)

我想要完成的是,基于树的总高度,我将调整节点的当前高度,因此根为 0,然后级别 1 为 1,依此类推。

我知道我实际上在每个级别都通过了两次高度,并且我没有通过树的总高度。我该怎么做才能真正获得每个递归级别的树的总高度?

4

1 回答 1

2

只需将另一个参数添加到prettyTree. 类似的东西padding :: Int。然后向左右子树添加replicate padding ' '空格middle并传递padding + 2给。prettyTree

请注意,您真正想要的是定义prettyTree t = paddedPrettyTree t 2以免更改prettyTree.

于 2013-10-06T08:33:13.023 回答