Я думал о выравнивании двоичного дерева в списке, для последней обработки.
Сначала я подумал о том, чтобы использовать (++)
для объединения левой и правой ветвей, но затем подумал, что в худшем случае это займет время O(n^2)
.
Затем я подумал о том, чтобы создать список назад, используя (:)
для добавления вперед в линейное время. Тем не менее, тогда я подумал, что если я отправлю этот список в функцию типа сгиба, ему придется подождать, пока все дерево не пройдет, прежде чем оно начнет складываться, и, следовательно, не может использовать список слитый.
Затем я придумал следующее:
data Tree a = Node a (Tree a) (Tree a) | Tip
flatten :: Tree a -> [a]
flatten x = (flatten' x) []
flatten' :: Tree a -> [a] -> [a]
flatten' (Node x left right) l = (flatten' left (x:(flatten' right l)))
flatten' Tip l = l
main =
putStrLn $ show $ flatten $
(Node 2 (Node 1 Tip Tip) (Node 4 (Node 3 Tip Tip) Tip))
Будет ли это работать в O(n)
раз, принять "пространство стека" не более чем пропорционально наибольшей глубине дерева и может ли оно быть слито с потребляющей функцией (т.е. промежуточным списком исключено)? Это "правильный" способ сгладить дерево?