[英]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 Int
與Tree
。
為每個圖層創建一個元素列表,然后檢查所有這些元素是否已排序。 假設你有一個功能
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.