我正在编写一个函数来获取二叉树并以正确的顺序打印出它的值(按顺序颠倒).我遇到的问题是,当我调用函数时,我一直得到一个非详尽的模式错误
--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=""
Run Code Online (Sandbox Code Playgroud)
你似乎已经解决了你的问题,除了你需要一些括号和空格.
我假设你正在使用
data Tree k d = Nil | Node (Tree k d) k d (Tree k d)
Run Code Online (Sandbox Code Playgroud)
虽然你没说.我将定义一个或两个示例树:
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)))
Run Code Online (Sandbox Code Playgroud)
你的功能
treeprint (Node l k d r) = treeprint l ++ show k ++ show d ++ treeprint r
treeprint Nil = ""
Run Code Online (Sandbox Code Playgroud)
编译好但是因为没有空格或括号,输出很混乱:
*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"
Run Code Online (Sandbox Code Playgroud)
它按顺序排列,但一起压扁,树形结构消失了.
让我们用每个树周围的括号和空格重写它:
tree_print (Node l k d r) = " (" ++ treeprint l ++ show k ++ ":" ++ show d ++ treeprint r ++ ") "
tree_print Nil = ""
Run Code Online (Sandbox Code Playgroud)
所以它现在更加清晰:
*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") ) ) )
Run Code Online (Sandbox Code Playgroud)
也许你不想要括号,因为顺序打印是为了使树变平.你可以保留空间和它:
,它会工作.或者,定义
toList :: Tree k d -> [(k,d)]
toList Nil = []
toList (Node t1 k d t2) = toList t1 ++ (k,d):toList t2
Run Code Online (Sandbox Code Playgroud)
这意味着您可以将该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")]
Run Code Online (Sandbox Code Playgroud)
这里的打印用树的方式Data.Tree.Pretty
从漂亮的树库.
我必须做一些导入:
import qualified Data.Tree as T
import Data.Tree.Pretty
Run Code Online (Sandbox Code Playgroud)
我导入了Data.Tree
qualified,因为它还定义了一个数据构造函数Node
.这意味着T.Node
当我指的是导入的树时我会使用,但就Node
在我指的是你的时候.
它使用玫瑰树(每个节点可以拥有尽可能多的子树):
data Tree a = Node {
rootLabel :: a, -- ^ label value
subForest :: Forest a -- ^ zero or more child trees
}
Run Code Online (Sandbox Code Playgroud)
并定义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]
Run Code Online (Sandbox Code Playgroud)
现在让我们展示(制作一个字符串)并打印(在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
Run Code Online (Sandbox Code Playgroud)
这提供了很好的输出:
*Main> printtree example1
7:"there"
|
---------
/ \
4:"Hello" 21:"hi"
| |
-- --
/ \ / \
- - - -
Run Code Online (Sandbox Code Playgroud)
并且通过稍微大一些的例子相当优雅地应对:
*Main> printtree example2
34:"well"
|
------------------------
/ \
7:"there" 55:"This"
| |
--------- -------------
/ \ / \
4:"Hello" 21:"hi" - 102:"much"
| | |
-- -- ------------
/ \ / \ / \
- - - - 73:"one's" 132:"bigger"
| |
-- --
/ \ / \
- - - -
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1190 次 |
最近记录: |