Продолжая работу, продвинулся еще чуть дальше (да тяжело идет постоянно встречаю тупики), я сумел оптимизировать немножко функцию вставки, и немножко подкорректировать функцию удаления (теперь бесконечной рекурсии нет, однако при выводе случается тупик, так как функция root упирается в пустоту.
module Main where
data BTree a = Nil | Node a (BTree a) (BTree a)
deriving (Eq, Show)
root :: BTree Int -> Int
root (Node a _ _) = a
getLeftBranch :: BTree Int -> BTree Int
getLeftBranch (Node _ b _) = b
getRightBranch :: BTree Int -> BTree Int
getRightBranch (Node _ _ c) = c
isNil :: BTree Int -> Bool
isNil Nil = True
isNil _ = False
isNonNil :: BTree Int -> Bool
isNonNil (Node _ _ _) = True
isNonNil _ = False
isLeaf :: BTree Int -> Bool
isLeaf (Node _ Nil Nil) = False
isLeaf _ = False
empty :: BTree Int
empty = Nil
leaf :: Int -> BTree Int
leaf a = Node a Nil Nil
deepTree :: BTree Int -> Int
deepTree tree | (isNil tree) = 0
| (isLeaf tree) = 1
| otherwise = if deepTree (getRightBranch tree) >= deepTree (getLeftBranch tree) then 1 + deepTree (getRightBranch tree)
else 1 + deepTree (getLeftBranch tree)
insertTree :: Int -> BTree Int -> BTree Int
insertTree x tree | (isNil tree) = leaf x
| deepTree (getLeftBranch tree) <= deepTree (getRightBranch tree) = if x >= root tree then Node (root tree) (insertTree x (getLeftBranch tree)) (getRightBranch tree)
else Node x (insertTree (root tree) (getLeftBranch tree)) (getRightBranch tree)
| otherwise = if x >= root tree then Node (root tree) (getLeftBranch tree) (insertTree x (getRightBranch tree))
else Node x (getLeftBranch tree) (insertTree (root tree) (getRightBranch tree))
pop :: BTree Int -> BTree Int
pop tree | (isLeaf tree) = empty
| (isNil (getRightBranch tree)) = Node (root (getLeftBranch tree)) (pop (getLeftBranch tree)) (empty)
| (isNil (getLeftBranch tree)) = Node (root (getRightBranch tree)) (empty) (pop (getRightBranch tree))
| otherwise = if root (getLeftBranch tree) <= root (getRightBranch tree) then Node (root (getLeftBranch tree)) (pop (getLeftBranch tree)) (empty)
else Node (root (getRightBranch tree)) (empty) (pop (getRightBranch tree))
fromListtoTree :: [Int] -> BTree Int -> BTree Int
fromListtoTree [] tree = tree
fromListtoTree (x:xs) tree = fromListtoTree xs (insertTree x tree)
treeOutput :: BTree Int -> IO()
treeOutput tree | (isNil tree) = print ""
| otherwise = do print (root tree)
treeOutput (pop tree)
main :: IO()
main = treeOutput (fromListtoTree [1, 2, 3, 4, 5, 6, 7] (empty))
И я честно не понимаю, где ошибка. На бумаге мой алгоритм работает, я пытался донести до Haskell следующие декларации (где в коде ошибка):
deepTree tree : Глубина пустого дерева - 0
Глубина непустого дерева - 1 + глубина "самого глубокого потомка"
insertTree x tree: Когда вставляем х в пустоту, то ответ листовая вершина с х.
Когда вставляем х в непустое дерево, то если х больше значения внутри дерева, тогда ответ дерево внутри которого прежнее значение, вставка х в потомка с наименьшей глубиной, и оставшийся потомок, иначе ответ есть дерево внутри которого х, один потомок которого есть вставка значения, хранившегося в этой веришине в потомка наименьшей глубины, и другой нетронутый потомок..
pop tree: Когда выбрасываем значение вершины листовой вершины - получаем пустоту.
Когда выбрасываем значение вершины из вершины, имеющей лишь 1 потомка - ответ есть дерево, внутри которого значение единственного потомка, а потомок такого дерева - изначальный потомок с выкинутой веришиной.
Когда выбрасываем значение из узла, то ответом является дерево внутри которого значение наименьшего из потомков, а его потомки - один нетронутый потомок и потомок с отброшенной веришиной.
По идее такой алгоритм должен успешно вставлять элементы в деревья и успешно отбрасывать вершины деревьев, заменяя их на наименьшего из потомков.
P.S. Заранее благодарю за помощь, извините что я такой тугодум.