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