栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Haskell构造binary Tree|99题(55)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Haskell构造binary Tree|99题(55)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录
  • 前言
  • 1 基本数据结构
    • 1.1 例子
  • 2 一些题目
    • 2.1 Construct completely balanced binary trees
  • 总结


前言

关于刷haskell题目对于tree的整理。
以下代码来自:WIKI99

1 基本数据结构
data Tree a = Empty | Branch a (Tree a) (Tree a)
              deriving (Show, Eq)
leaf x = Branch x Empty Empty
1.1 例子
-- A binary tree consisting of a root node only
tree2 = Branch 'a' Empty Empty

-- An empty binary tree
tree3 = Empty

-- A tree of integers
tree4 = Branch 1 (Branch 2 Empty (Branch 4 Empty Empty))
                 (Branch 2 Empty Empty)
                 
2 一些题目 2.1 Construct completely balanced binary trees

要求构成平衡二叉树 :
平衡:左边和右边的差距最大为1
二叉树:一个Branch只有两个sub tree

λ> cbalTree 4
[
-- permutation 1
--     x
--    / 
--   x   x
--        
--         x
Branch 'x' (Branch 'x' Empty Empty) 
           (Branch 'x' Empty 
                       (Branch 'x' Empty Empty)),

-- permutation 2
--     x
--    / 
--   x   x
--      /
--     x
Branch 'x' (Branch 'x' Empty Empty) 
           (Branch 'x' (Branch 'x' Empty Empty) 
                       Empty),

-- permutation 3
--     x
--    / 
--   x   x
--    
--     x
Branch 'x' (Branch 'x' Empty 
                       (Branch 'x' Empty Empty)) 
           (Branch 'x' Empty Empty),

-- permutation 4
--     x
--    / 
--   x   x
--  /
-- x
Branch 'x' (Branch 'x' (Branch 'x' Empty Empty) 
                       Empty) 
           (Branch 'x' Empty Empty)
]

Answer 1:

cbalTree 0 = [Empty]
cbalTree 1 = [leaf 'x']
cbalTree n = if n `mod` 2 == 1 then 
             [ Branch 'x' l r | l <- cbalTree ((n - 1) `div` 2), 
                                r <- cbalTree ((n - 1) `div` 2) ] 
             else 
             concat [ [Branch 'x' l r, Branch 'x' r l] | l <- cbalTree ((n - 1) `div` 2), 
                                                         r <- cbalTree (n `div` 2) ]
  1. 要注意最后得到的是一个tree list
  2. list comprehension 去罗列所有可能的tree
  3. 只有两种情况 : 完全balence ; 不完全balence
  4. concat 使用注意去掉一层括号

Answer 2:
这个答案很具有参考性,更加具有普遍性
可以用于其他场景: 左树比右树高2;3;4…

main = putStrLn $ concatMap (t -> show t ++ "n") balTrees
    where balTrees = filter isBalancedTree (makeTrees 'x' 4)

isBalancedTree :: Tree a -> Bool
isBalancedTree Empty = True
isBalancedTree (Branch _ l r) = abs (countBranches l - countBranches r) <= 1
                                && isBalancedTree l && isBalancedTree r
isBalancedTree _ = False

countBranches :: Tree a -> Int
countBranches Empty = 0
countBranches (Branch _ l r) = 1 + countBranches l + countBranches r

-- makes all possible trees filled with the given number of nodes
-- and fill them with the given value
makeTrees :: a -> Int -> [Tree a]
makeTrees _ 0 = []
makeTrees c 1 = [leaf c]
makeTrees c n = lonly ++ ronly ++ landr
    where lonly  = [Branch c t Empty | t <- smallerTree]
          ronly = [Branch c Empty t | t <- smallerTree]
          landr = concat [[Branch c l r | l <- fst lrtrees, r <- snd lrtrees] | lrtrees <- treeMinusTwo]
          smallerTree = makeTrees c (n-1)
          treeMinusTwo = [(makeTrees c num, makeTrees c (n-1-num)) | num <- [0..n-2]]

concat 是在2 个for循环的情况下
弄清循环的分级很重要


总结
  1. Haskell里的循环要多考虑list comprehension。
  2. 循环要注意考虑条件的分级, 比如代码中要对同一棵树取fst snd
  3. 循环分级时需用concat
  4. 从最基本的树开始分析,一层一层往上照,总归会找出规律,Haskell递归的本质就是,发现规律并表示出来。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/996605.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号