在Haskell中显示二叉树

时间:2014-03-10 02:00:18

标签: haskell binary-tree

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

我正试图找出一种方式来显示二叉树,使得对于每个级别我在树中下来,我想在节点名称旁边添加一个额外的*并将它们全部分开\n

例如:

let x = Node "Parent" (Node "childLeft" (Node "grandChildLeftLeft" Emp Emp) Emp) (Node "childRight" Emp Emp)
putStrLn $ displayTree x

应该返回:

"Parent"
*"childLeft"
**"grandChildLeftLeft"
*"childRight"

我的功能(最多只打印一个*):

displayTree :: Show a => BinTree a -> String
displayTree Emp = ""
displayTree (Node head Emp Emp) = (show head)
displayTree (Node head left Emp) = (show head) ++ "\n*" ++ displayTree left
displayTree (Node head Emp right) = (show head) ++ "\n*" ++ displayTree right
displayTree (Node head left right) = (show head) ++ "\n*" ++ displayTree left ++ "\n*" ++ displayTree right

我的displayTree功能会打印出来:

"Parent"
*"childLeft"
*"grandChildLeftLeft"
*"childRight"

我希望"grandChildLeftLeft"旁边有**而不只是*

有什么建议吗?

注意:我不想更改传递给函数的参数,因此它应保持为displayTree :: Show a => BinTree a -> String

2 个答案:

答案 0 :(得分:3)

我认为这就是你想要的:

module Main (main) where

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

showTree :: Show a => BinTree a -> Int -> String
showTree (Empty) _ = []
showTree (Node t l r) n = replicate n '*' ++ show t ++ "\n" ++ showTree l (n+1) ++ showTree r (n+1)

main :: IO ()
main = do
    let x = Node "Parent" (Node "childLeft" (Node "grandChildLeftLeft" Empty Empty) Empty) (Node "childRight" Empty Empty)
    putStrLn $ showTree x 0

请注意累加器n,它会在每次递归调用时更改缩进级别。


http://ideone.com/lphCoV

"Parent"
*"childLeft"
**"grandChildLeftLeft"
*"childRight"

答案 1 :(得分:0)

为什么不将深度传递给displayTree函数?

displayTree :: Show a => BinTree a -> String 
displayTree = displayTree' ""

displayTree' str Emp = ""
displayTree' str (Node head Emp Emp) = str ++ (show head)
displayTree' str (Node head left Emp) = str ++ (show head) ++ "\n" ++ displayTree' (str ++ "*") left
displayTree' str (Node head Emp right) = str ++ (show head) ++ "\n" ++ displayTree' (str ++ "*") right
displayTree' str (Node head left right) = str ++ (show head) ++ "\n" ++ displayTree' (str ++ "*") left ++ "\n" ++ displayTree (str ++ "*") right

此外,这里重构的是更具可读性:

displayTree :: Show a => BinTree a -> String 
displayTree = displayTree' ""

displayTree' str Empty = ""
displayTree' str (Node h l r) = hstr ++ lstr ++ rstr
    where
        hstr = str ++ (show head) ++ "\n"
        lstr = makeTreeStr l
        rstr = makeTreeStr r
        makeTreeStr Empty = ""
        makeTreeStr tree = displayTree' (str ++ "*") tree ++ "\n"