Haskell の学習の一環として、バイナリ ツリーを作成することにしました。
私が理解している限り、挿入と削除の大きなセットをシーケンスすると、結果のツリーが比較的小さい場合でも、最終的に評価を開始するとスタックオーバーフローに簡単に到達する可能性があります。
ここに私の質問があります:
関数に厳密さを導入することでこれを回避できますか? (seq / deepseqの何か?)。
どのような状況で挿入/削除を現在の状態に保ちたいですか?
コードの設計が悪い、または間違っていると思われる場合は、遠慮なくコードを修正または改善してください。
関連するコード:
import Data.List
data Tree a = Empty | Branch a (Tree a) (Tree a)
deriving (Eq)
leaf x = Branch x Empty Empty
-- insert ------------------------------------
treeInsert :: (Eq a, Ord a) => Tree a -> a -> Tree a
treeInsert Empty x = leaf x
treeInsert (Branch y l r) x | x<y = Branch y (treeInsert l x) r
| x>y = Branch y l (treeInsert r x)
| otherwise = Branch x l r --edit
-- delete ------------------------------------
treeDelete :: (Eq a, Ord a) => Tree a -> a -> Tree a
treeDelete Empty _ = Empty
treeDelete (Branch y l r ) x | y<x = Branch y l (treeDelete r x)
| y>x = Branch y (treeDelete l x) r
| y==x = del' $ Branch y l r
where
-- if this Branch is a leaf dispose of it.
-- if branch has only one child return the child (skip over).
-- otherwise, replace this branch with its successor (the leftmost child of the right tree)
-- successor will be extracted from its original location.
del' ( Branch y Empty Empty ) = Empty
del' ( Branch y Empty r ) = r
del' ( Branch y l Empty ) = l
del' ( Branch y l r ) = Branch ySucc l rWithout_ySucc
where
( rWithout_ySucc, ySucc ) = leftmost r
where
leftmost ( Branch y Empty Empty ) = ( Empty, y )
leftmost ( Branch y Empty r ) = ( r, y )
leftmost ( Branch y l r ) = ( Branch y ll r, z ) where ( ll, z ) = leftmost l