2013-02-26 79 views
1

假设我有一棵二叉树。在Haskell中,一个漂亮的打印递归深度如何?

main = putStrLn $ printTree tree                                             

data Tree = Empty | Node Int (Tree) (Tree) deriving (Show)                                      

tree = Node 4 (Node 3 Empty (Node 2 Empty Empty)) Empty                                       

printTree :: Tree -> String                                              
printTree x = case x of                                               
    Node num treeA treeB -> show num ++ "\n" ++ printTree treeA ++ "\n" ++ printTree treeB                               
    Empty -> "Empty" 

输出

*Main> main                                                  
4                                                    
3                                                    
Empty                                                   
2                                                    
Empty                                                   
Empty                                                   
Empty 

所需的输出(通过选项卡或双空格分隔是罚款)

*Main> main                                                  
    4                                                    
     3                                                    
     Empty                                                   
     2                                                    
      Empty                                                   
      Empty                                                   
     Empty 
+0

首先返回'[String]',而不是'String'。使输出成为行列表可让您轻松修改递归调用产生的每一行。 – Carl 2013-02-26 02:04:03

回答

2

可以使用累加器(这里,depth)保持跟踪有多深您目前正在树中 - 然后创建与该线的深度对应的多个空格:

main = putStrLn $ printTree tree 
data Tree = Empty | Node Int (Tree) (Tree) deriving (Show) 
tree = Node 4 (Node 3 Empty (Node 2 Empty Empty)) Empty 

printTree :: Tree -> String 
printTree x = printTree' x 0 
    where 
    printTree' x depth = case x of 
     Node num treeA treeB -> (replicate (2 * depth) ' ') ++ show num ++ "\n" ++ (printTree' treeA (depth + 1)) ++ "\n" ++ (printTree' treeB (depth + 1)) 
     Empty -> (replicate (2 * depth) ' ') ++ "Empty" 

输出:

*Main> main 
4 
    3 
    Empty 
    2 
     Empty 
     Empty 
    Empty 
0

好吧,我想我得到它的工作。

printTree :: Tree -> String                                              
printTree x = printT 0 x                                                     

space x = take x $ cycle " "                                              

printT :: Int -> Tree -> String                                             
printT num x =                                                 
    case x of                                                  
    (Node o treeA treeB) -> show o ++                                           
          "\n" ++                                            
          space num ++                                           
          printT (num+1) treeA ++                                        
          "\n" ++                                            
          space num ++                                           
          printT (num+1) treeB                                         
    Empty -> "Empty" 
1

下面是一个使用-XImplicitParams在GHC的解决方案

{-# LANGUAGE ImplicitParams #-} 
module ImplicitTabs where 

data Tree = Empty | Node Int (Tree) (Tree) deriving (Show) 
tree = Node 4 (Node 3 Empty (Node 2 Empty Empty)) Empty           

tab :: (?tab_level :: Int) => String 
tab = replicate (2 * ?tab_level) ' ' 

printTree :: (?tab_level :: Int) => Tree -> String 
printTree x = let 
    ?tab_level = ?tab_level + 1 
    in case x of 
    Node num treeA treeB -> tab ++ show num ++ "\n" ++ tab ++ printTree treeA ++ "\n" ++ tab ++ printTree treeB 
    Empty -> tab ++ "Empty" 

main = let ?tab_level = -1 in putStrLn $ printTree tree 


> runhaskell implicit-tabulation.hs 
4 
    3 
     Empty 
     2 
      Empty 
      Empty 
    Empty 
+1

IMO'ImplicitParams'在这里完全是矫枉过正。一个常规的参数应该没问题... – luqui 2013-03-07 07:29:47

0

如果转换为Data.Tree,那么你可以使用库函数drawTree这也几乎是你在找什么(它也借鉴分支与ASCII艺术)。