反向猴子拼图排序(Haskell)

时间:2013-07-24 11:32:45

标签: list sorting haskell binary-tree puzzle

我在Augest中重复Haskell所以我正在尝试练习我的Haskell。 其中一个问题是:

“通过将列表的元素存储到二叉树中然后遍历树以执行子树的节点以顺序正确的子,父,然后左子,来执行反向猴子拼图列表的列表在Haskell中写一个反向猴子拼图排序“

这个问题让我很困惑。 我知道我必须写一个函数去xr Node xl。 但这是否必须从遍历的树输出列表?或者我用列表重新填充二叉树还是什么? 另外,我会从最右边的元素开始,然后转到那个父母,然后向左转,或者从树顶部的第一个根节点开始,然后就这样开始吗?

另外,我将如何编写它,Haskell是我的弱点之一。 感谢任何帮助!

这是我的代码

module Data.BTree where

data Tree a = Tip | Node a (Tree a) (Tree a) deriving (Show,Eq)

leaf x = Node x Tip Tip

t1 = Node 10 Tip Tip
t2 = Node 17 (Node 12 (Node 5 Tip(leaf 8)) (leaf 15))
         (Node 115
                (Node 32 (leaf 30) (Node 46 Tip (leaf 57)))
                (leaf 163))
t3 = Node 172 (Node 143 (Node 92 (Node 76 (leaf 32) (leaf 45)) (Node 58 (leaf 39) (leaf 52))) (Node 107 (Node 92 (leaf 64) (leaf 35)) (Node 86 (leaf 69) (leaf 70))))
          (Node 155 (Node 127 (leaf 83) (leaf 97)) (Node 138 (leaf 107) (leaf 91)))

1 个答案:

答案 0 :(得分:2)

你可以写

data Tree a = Empty | Tree (Tree a) a (Tree a)

ins :: Ord a => Tree a -> a -> Tree a
ins Empty x = Tree Empty x Empty
ins (Tree l y r) x = if x < y then Tree (ins l x) y r else Tree l y (ins r x)

fromList :: Ord a => [a] -> Tree a
fromList = foldl ins Empty -- <<< FOLDABLE

toList :: Ord a => Tree a -> [a]
toList Empty = []
toList (Tree l x r) = (toList l) ++ [x] ++ (toList r) -- <<< MONOID
                                                      -- (change order if you wish)

sort :: Ord a => [a] -> [a]
sort = toList . fromList

直接解决您的问题。

一般情况下,使用更为抽象的结构(例如monoidfoldable,......你可以(必须)阅读Learn You Haskell for Great Good!

:)

实施例

*Main> sort [6, 3, 7, 8, 3, 6]
[3,3,6,6,7,8]

如评论(代码中),更常见的方法是将一些有用的结构定义到TreeFoldableMonoid和其他结构。

假设我们已经实现了两个结构:

import Data.Foldable
import Data.Monoid

data Tree a = Empty | Tree (Tree a) a (Tree a) deriving Show

-- Shortcut
leaf :: Ord a => a -> Tree a
leaf x = Tree Empty x Empty

instance Foldable Tree where
    foldMap f Empty = mempty
    foldMap f (Tree l k r) = foldMap f l `mappend` f k `mappend` foldMap f r

-- WARNING: in that monoid only traverse result (ordered list) is invariant!
instance Ord a => Monoid (Tree a) where
    mempty = Empty
    mappend Empty tree = tree
    mappend tree Empty = tree
    mappend (Tree l x r) tree = ins (l `mappend` r `mappend` tree) x
        where ins Empty x = leaf x
              ins (Tree l y r) x = if x < y then Tree (ins l x) y r else Tree l y (ins r x)

在Haskell中很常见。

现在,您的问题(使用加载/卸载树在列表上定义sort)只是:

sort :: Ord a => [a] -> [a]
sort = foldMap return . foldMap leaf

this question

中,@ m0nhawk,@tel和@ petr-pudlak详细介绍了一种更为通用的方法(结构)