Я занимаюсь самообучением Чисто функциональные структуры данных Окасаки, теперь в упражнении 3.4 , которое просит рассуждать и реализовывать смещенную в сторону левую кучу. Это моя основная реализация:
(* 3.4 (b) *)
functor WeightBiasedLeftistHeap (Element : Ordered) : Heap =
struct
structure Elem = Element
datatype Heap = E | T of int * Elem.T * Heap * Heap
fun size E = 0
| size (T (s, _, _, _)) = s
fun makeT (x, a, b) =
let
val sizet = size a + size b + 1
in
if size a >= size b then T (sizet, x, a, b)
else T (sizet, x, b, a)
end
val empty = E
fun isEmpty E = true | isEmpty _ = false
fun merge (h, E) = h
| merge (E, h) = h
| merge (h1 as T (_, x, a1, b1), h2 as T (_, y, a2, b2)) =
if Elem.leq (x, y) then makeT (x, a1, merge (b1, h2))
else makeT (y, a2, merge (h1, b2))
fun insert (x, h) = merge (T (1, x, E, E), h)
fun findMin E = raise Empty
| findMin (T (_, x, a, b)) = x
fun deleteMin E = raise Empty
| deleteMin (T (_, x, a, b)) = merge (a, b)
end
Теперь, в 3.4 (c) и (d), он спрашивает:
В настоящее время merge
работает в двух
проходит: проход сверху вниз, состоящий из
звонки на merge
и восходящий проход
состоящий из обращений к помощнику
функция, makeT
. Изменить merge
на
работать в один проход сверху вниз.
Какие преимущества даст нисходящий
версия merge
есть у ленивых
среда? В одновременной
окружающая среда
Я изменил функцию merge
, просто вставив makeT
, но я не вижу никаких преимуществ, поэтому думаю, что не понял дух этих частей упражнения. Чего мне не хватает?
fun merge (h, E) = h
| merge (E, h) = h
| merge (h1 as T (s1, x, a1, b1), h2 as T (s2, y, a2, b2)) =
let
val st = s1 + s2
val (v, a, b) =
if Elem.leq (x, y) then (x, a1, merge (b1, h2))
else (y, a2, merge (h1, b2))
in
if size a >= size b then T (st, v, a, b)
else T (st, v, b, a)
end
Мне кажется, я понял один момент в отношении ленивых оценок. Если я не использую рекурсивное слияние для вычисления размера, то рекурсивный вызов не нужно будет оценивать, пока не понадобится дочерний элемент:
fun merge (h, E) = h
| merge (E, h) = h
| merge (h1 as T (s1, x, a1, b1), h2 as T (s2, y, a2, b2)) =
let
val st = s1 + s2
val (v, ma, mb1, mb2) =
if Elem.leq (x, y) then (x, a1, b1, h2)
else (y, a2, h1, b2)
in
if size ma >= size mb1 + size mb2
then T (st, v, ma, merge (mb1, mb2))
else T (st, v, merge (mb1, mb2), ma)
end
Это все? Я не уверен насчет параллелизма.