簡體   English   中英

檢查在Haskell中是否從左向右遍歷了二叉樹

[英]Check if a binary tree is traversed from left to right in Haskell

我有以下樹,這就是我訪問其節點和葉子的Int值的方式。 我想做的是編寫一個函數“ areValuesIncreasing”來檢查當樹從左向右遍歷時節點/葉子的值是否在增加。 任何幫助,將不勝感激。

       4                    4
     /   \                /   \
    2     3              3     2
   / \   / \            / \   / \
  1   3 4   5  - True  1   3 5   4 - False



   data Tree = Node Tree Int Tree | Leaf Int deriving Show

   treeToInt (Node _ n _) = n
   treeToInt (Leaf n ) = n

   areValuesIncreasing:: Tree -> Bool

我強烈建議將Tree更改為

data Tree a = Node (Tree a) a (Tree a)
            | Leaf a 
            deriving (...)

並會在我的答案用這個,但將其轉化為你的Tree是設置簡單a ~ Int無處不在,更換Tree IntTree

為每個圖層創建一個元素列表,然后檢查所有這些元素是否已排序。 假設你有一個功能

foldTree :: (a -> b) ->           -- Leaf case
            (b -> a -> b -> b) -> -- Node case
            Tree a -> b

葉子產生一個包含單例列表的列表,后跟repeat [] ,因為葉子是一個級別上的單個元素,后面是無限多個空級別

leafCase x = [x] : repeat []

內部節點將子樹的列表的子列表成對連接,同時還將其元素放在頂部的單例列表中:

nodeCase l x r = [x] : zipWith (++) l r

將其折疊到Tree以獲取級別列表,並在最后一個非空級別之后將其切斷:

levels = takeWhile (not . null) . foldTree leafCase nodeCase

檢查每個級別是否已排序:

sorted = all (uncurry (<=)) . (zip <*> tail)

將其混合成一個函數

sortedTree = all sorted . takeWhile (not . null) . levels
  where sorted = all (uncurry (<=)) . (zip <*> tail)
        levels = foldTree (\l -> [l] : repeat []) (\l x r -> [x] : zipWith (++) l r)

recursion-schemes

makeBaseFunctor ''Tree
-- data TreeF a b = NodeF b a b | LeafF a
-- ...
levelsSorted :: (Recursive t, Foldable (Base t), Ord a) => (Base t [[a]] -> a) -> t -> Bool
levelsSorted get = all sorted . takeWhile (not . null) . levels
    where sorted = all (uncurry (<=)) . (zip <*> tail)
          levels = cata $ \x -> [get x] : foldr (zipWith (++)) (repeat []) x

levelsSortedTree :: Ord a => Tree a -> Bool
levelsSortedTree = levelsSorted $ \case { LeafF _ x _ -> x; NodeF x -> x }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM