解 感谢KarolisJuodelė,这是我解决这个问题的优雅方案!谢谢KarolisJuodelė:
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,因此堡垒。
据我所知,我实际上每个级别传递两次高度,而我没有超过树的总高度。我可以做些什么来实际获得每个递归级别的树的总高度?
答案 0 :(得分:2)
只需将另一个参数添加到prettyTree
即可。像padding :: Int
这样的东西。然后将replicate padding ' '
个空格添加到middle
,并将padding + 2
传递给左右子树的prettyTree
。
注意,您真正想要的是定义prettyTree t = paddedPrettyTree t 2
以便不更改prettyTree
的类型。