1
鑑於二叉樹使用翻轉操作符對二叉樹進行後序遍歷。左邊評估右邊?
data BinaryTree a =
Leaf
| Node (BinaryTree a) a (BinaryTree a)
deriving (Show)
我的解決方案,以預購/序使用:
preorder :: BinaryTree a -> [a]
preorder Leaf = []
preorder (Node left x right) = x : preorder left ++ preorder right
inorder :: BinaryTree a -> [a]
inorder Leaf = []
inorder (Node left x right) = inorder left ++ (x : inorder right)
但對後序完成的,這並不工作:
postorder :: BinaryTree a -> [a]
postorder Leaf = []
postorder (Node left x right) = (postorder left ++ postorder right) : x
是理所當然的因爲我想出了這種類型的簽名是
(:) :: a -> [a] -> [a]
我以爲我可以這樣做解決這個問題:
append :: [a] -> a -> [a]
append = flip (:)
postorder :: BinaryTree a -> [a]
postorder Leaf = []
postorder (Node left x right) = (postorder left ++ postorder right) `append` x
但最終它給我相同的答案preorder
。我很困惑,因爲我認爲左手邊會在右手邊進行評估。
我以爲這是因爲我知道後序也可以這樣解決(這個方法不是一個球迷,因爲它意味着使XA列表無故,但追加):
postorder (Node left x right) = postorder left ++ postorder right ++ [x]
是否有人可以告訴我我出錯的地方,也許爲什麼後序與前序有相同的結果?
「不是這種方法的粉絲,因爲它意味着讓x成爲一個無緣無故的列表,但要追加」 - 如果您將元素放在列表的末尾,則沒有選擇。你可以寫一個函數'snoc :: [a] - > a - > [a]',但它永遠不會比'\ xs x - > xs ++ [x]'更好。 – user2407038
「我認爲左手邊將在右手邊之前進行評估。」評估順序在Haskell中並不重要。你的問題是'append list x',根據它的定義,插入''''''''list''。 – chi
雖然有一種不喜歡'xs ++ [x]'的合法理由,這是一個O(n)操作。考慮使用[差異列表](https://wiki.haskell.org/Difference_list)。 – chepner