3

Haskell の学習の一環として、バイナリ ツリーを作成することにしました。

私が理解している限り、挿入と削除の大きなセットをシーケンスすると、結果のツリーが比較的小さい場合でも、最終的に評価を開始するとスタックオーバーフローに簡単に到達する可能性があります。

ここに私の質問があります:

  1. 関数に厳密さを導入することでこれを回避できますか? (seq / deepseqの何か?)。

  2. どのような状況で挿入/削除を現在の状態に保ちたいですか?

コードの設計が悪い、または間違っていると思われる場合は、遠慮なくコードを修正または改善してください。

関連するコード:

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
4

1 に答える 1