data AVL t = Empty | Node t (AVL t) (AVL t) Int
deriving (Eq, Ord, Show)
insertNode :: (Ord a) => a -> AVL a -> AVL a
insertNode x Empty = Node x Empty Empty 0
insertNode x (Node n left right balanceFactor)
| x < n = let leftNode = insertNode x left
in
balanceTree (Node n leftNode right ((treeHeight leftNode) - (treeHeight right)))
| otherwise = let rightNode = insertNode x right
in
balanceTree (Node n left rightNode ((treeHeight left) - (treeHeight rightNode)))
findNode :: AVL a -> a
findNode Empty = error "findNode from Empty"
findNode (Node a _ _ _) = a
findLeftNode :: AVL a -> AVL a
findLeftNode Empty = error "findLeftNode from Empty"
findLeftNode (Node _ left _ _) = left
findRightNode :: AVL a -> AVL a
findRightNode Empty = error "findRightNode from Empty"
findRightNode (Node _ _ right _) = right
findBalanceFactor :: AVL a -> Int
findBalanceFactor Empty = 0
findBalanceFactor (Node _ _ _ bf) = bf
treeHeight :: AVL a -> Int
treeHeight Empty = 0
treeHeight (Node _ left right _) = 1 + (max (treeHeight left) (treeHeight right))
balanceTree :: AVL a -> AVL a
balanceTree Empty = Empty
balanceTree (Node r Empty Empty bf) = Node r Empty Empty bf
balanceTree (Node r left right bf)
| bf == -2 && rbf == -1 = let rl = (findLeftNode right)
in
(Node (findNode right) -- This is for the
(Node r left rl ((treeHeight left) - (treeHeight rl))) -- "right right" case
(findRightNode right)
((1 + (max (treeHeight left) (treeHeight rl))) - (treeHeight (findRightNode right)))
)
| bf == -2 && rbf == 1 = let rl = findLeftNode right
rr = findRightNode right
in
(Node (findNode (rl)) -- This is for the
(Node r left (findLeftNode rl) ((treeHeight left) - (treeHeight (findLeftNode rl)))) -- "right left" case
(Node (findNode right) (findRightNode rl) rr ((treeHeight (findRightNode rl)) - (treeHeight rr)))
((max (treeHeight left) (treeHeight (findLeftNode rl))) - (max (treeHeight (findRightNode rl)) (treeHeight rr)))
)
| bf == 2 && lbf == 1 = let lr = findRightNode left
in
(Node (findNode left) -- This is for the
(findLeftNode left) -- "left left" case
(Node r lr right ((treeHeight lr) - (treeHeight right)))
((treeHeight (findLeftNode left)) - (1 + (max (treeHeight lr) (treeHeight right))))
)
| bf == 2 && lbf == -1 = let lr = findRightNode left
ll = findLeftNode left
in
(Node (findNode lr) -- This is for the
(Node (findNode left) ll (findLeftNode lr) ((treeHeight ll) - (treeHeight (findLeftNode lr)))) -- "left right" case
(Node r (findRightNode lr) right ((treeHeight (findRightNode lr)) - (treeHeight right)))
((max (treeHeight ll) (treeHeight (findLeftNode lr))) - (max (treeHeight(findRightNode lr)) (treeHeight right)))
)
| otherwise = (Node r left right bf)
where rbf = findBalanceFactor right
lbf = findBalanceFactor left
这是我实现AVL树的当前状态。正常的输入通常是:我需要帮助在Haskell上显示AVL树
insertNode 4 (Node 2 (Node 1 Empty Empty 0) (Node 3 Empty Empty 0) 0)
这导致:
Node 2 (Node 1 Empty Empty 0) (Node 3 Empty (Node 4 Empty Empty 0) (-1)) (-1)
我想现在有一个功能,以在一个整洁的方式直接在上面显示输入的树,例如,树:
2
1
Empty
Empty
3
Empty
4
Empty
Empty
有没有人有任何建议,如何可以实施?我希望仅显示节点,并且一旦到达分支的末尾,它将打印“空白”。我打了一堵砖墙,并尝试了几次尝试,但都取得了一些成功。
编辑:嗨,大家好,谢谢你的快速反应。你的建议可以工作,但是,我希望在不使用包或库的情况下显示树的实现。对不起,没有澄清这一点!
感谢您的快速帮助!你能否解释一下Data.Tree如何去做这件事?此外,对于此行 'test = putStrLn $ T.drawTree(toTree avl)' 'putStrLn $'完全是做什么的? 对不起,如果这是一个明显的答案,因为我习惯于调用函数并给出如 – PremiumWall
以上示例输入中的参数,'putStrLn $ ...'与'putStr(...)'相同 – ErikR