1

我目前正在编写一个函数来获取二叉树并以正确的顺序(按横向顺序)打印出它的值。我遇到的问题是,当我调用该函数时,我一直收到一个非详尽的模式错误

 --k is the key and d is the value
 -- l is left tree and r is right tree
treeprint (Node l k d r)      =  treeprint l  ++ show k ++ show d ++ treeprint r 
treeprint Nil=""
4

1 回答 1

6

似乎已经解决了你的问题,除了你需要一些括号和空格。

您的(当前)版本

我假设你正在使用

data Tree k d = Nil | Node (Tree k d) k d (Tree k d)

虽然你没说。我将定义一两个示例树:

example1, example2 :: Tree Int String
example1 = Node (Node Nil 4 "Hello" Nil) 7 "there" (Node Nil 21 "hi" Nil)
example2 = Node example1 34 "well" (Node Nil 55 "This" (Node (Node Nil 73 "one's" Nil) 102 "much" (Node Nil 132 "bigger" Nil)))

你的功能

treeprint (Node l k d r) =  treeprint l  ++ show k ++ show d ++ treeprint r 
treeprint Nil = ""

编译正常,但因为没有空格或括号,输出令人困惑:

*Main> putStrLn $ treeprint example1
4"Hello"7"there"21"hi"
*Main> putStrLn $ treeprint example2
4"Hello"7"there"21"hi"34"well"55"This"73"one's"102"much"132"bigger"

它是有序的,但被压在一起,树状结构消失了。

更多括号,更多空格,更清晰

让我们用每棵树周围的括号和空格来重写它:

tree_print (Node l k d r) = " (" ++ treeprint l  ++ show k ++ ":" ++ show d ++ treeprint r ++ ") "
tree_print Nil = ""

所以现在更清楚了:

*Main> putStrLn $ tree_print example1
 ( (4:"Hello") 7:"there" (21:"hi") ) 
*Main> putStrLn $ tree_print example2
 ( ( (4:"Hello") 7:"there" (21:"hi") ) 34:"well" (55:"This" ( (73:"one's") 102:"much" (132:"bigger") ) ) ) 

压平树并获得更多括号!

也许您不想要括号,因为按顺序打印是为了使树变平。你可以只保留空间:和它会工作。或者,定义

toList :: Tree k d -> [(k,d)]
toList Nil = []
toList (Node t1 k d t2) = toList t1 ++ (k,d):toList t2

这意味着您可以将Show实例用于列表:

*Main> toList example1
[(4,"Hello"),(7,"there"),(21,"hi")]
*Main> toList example2
[(4,"Hello"),(7,"there"),(21,"hi"),(34,"well"),(55,"This"),(73,"one's"),(102,"much"),(132,"bigger")]

更漂亮

这是一种使用漂亮树库中的 a 打印树Data.Tree.Pretty方法

我将不得不做一些导入:

import qualified Data.Tree as T
import Data.Tree.Pretty

我已经导入Data.Tree了qualified,因为它还定义了一个数据构造函数Node。这意味着T.Node当我指的是导入的树时,我会使用它,但Node我指的是你的树。

它使用玫瑰树(每个节点可以有任意数量的子树):

data Tree a = Node {
        rootLabel :: a,         -- ^ label value
        subForest :: Forest a   -- ^ zero or more child trees
    }

并定义drawVerticalTree :: Tree String -> String我将使用哪个。我们需要做的就是将您的树转换为这棵树,我们将开展业务:

toTree :: (Show k,Show d) => Tree k d -> T.Tree String
toTree Nil = T.Node "-" []
toTree (Node t1 k d t2) = T.Node (show k ++ ":" ++ show d) [toTree t1,toTree t2]

现在让我们显示(制作一个字符串)并打印(在 IO monad 中输出):

showtree :: (Show k, Show d) => Tree k d -> String
showtree = drawVerticalTree.toTree

printtree :: (Show k, Show d) => Tree k d -> IO ()
printtree = putStrLn.('\n':).showtree

这给出了很好的输出:

*Main> printtree example1

    7:"there"     
        |         
     ---------    
    /         \   
4:"Hello"  21:"hi"
    |         |   
    --        --  
   /  \      /  \ 
   -  -      -  - 

并且相当优雅地处理稍微大一点的例子:

*Main> printtree example2

                   34:"well"                   
                       |                       
         ------------------------              
        /                        \             
    7:"there"                55:"This"         
        |                        |             
     ---------       -------------             
    /         \     /             \            
4:"Hello"  21:"hi"  -         102:"much"       
    |         |                   |            
    --        --            ------------       
   /  \      /  \          /            \      
   -  -      -  -      73:"one's"  132:"bigger"
                           |            |      
                           --           --     
                          /  \         /  \    
                          -  -         -  -    
于 2012-11-18T15:37:26.577 回答