#<p>
# This file provides a class definition for a "Heap" - a priority
# queue implemented as a dense binary tree. The algorithms for
# manipulating the Heap are taken from code written by Kazimir
# Majorinc.
#</p>
#<p>
# A hallmark of this implementation is the flexibility - virtually
# any definition of "priority" may be used to define the ordering
# within the queue.
#</p>
#<p>
# Author: Steve Wampler (sbw@tapestry.tucson.az.us)
#</p>
#<p>
# <i>This file is in the public domain.</i>
#</p>
#<p>
# The collection package provides advanced data structures.
#</p>
package collection
import lang
import util
#<p>
# A Heap is a dense binary tree ordered as a <i>priority queue</i>.
# The priority order is from lowest to highest priority where the
# priority of two elements can be compared through the results
# of invoking the operation <i>f</i> on each. The priority operation
# <i>p</i> defaults to "<" but can be any binary comparison operation.
#</p>
#<p>
# Both f and p may be any of lang::Closure, procedure, function,
# integer, or string-invocation symbol. f is invoked with a single
# argument (a heap element) and p is invoked to compare the results
# of two calls to f.
#</p>
class Heap : Object (L, f, p)
#<p>
# <[generates the heap elements(non-destructively) in order]>
#</p>
method gen()
local temp := Heap(,f,p)
temp.L := ::copy(L)
suspend |temp.get()
end
#<p>
# <[returns the number of heap elements]>
#</p>
method size()
return *L
end
#<p>
# <[returns the top of the heap (non-destructively)]>
#</p>
method top()
return L[1]
end
#<p>
# <[return the next heap element (destructively, in order)]>
#</p>
method get()
local up, down, result
static call
initial call := invokeFcn
if *L > 0 then {
L[up:=1] :=: L[-1]
result := ::pull(L)
while (down := 2*up) <= *L do {
if call(p,call(f,L[down+1]), call(f,L[down])) then down +:= 1
if call(p,call(f,L[down]),call(f,L[up])) then L[up]:=:L[down]
up := down
}
return result
}
end
#<p>
# Add a new element to the heap.
# <[returns <tt>a</tt>]>
#</p>
method add(a # element to add
)
local i
static call
initial call := invokeFcn
::put(L,a)
i := *L
while call(p,call(f,L[i]), call(f,L[i/2])) do {
L[i] :=: L[i/2]
i /:= 2
}
return a
end
#<p>
# Construct a Heap.
# <[param S optional list of initial values to insert into heap]>
# <[param fVal a <tt>lang::Closure</tt>, procedure, integer, or
# string-invocation to use in comparisons. When needed,
# the operation is invoked with a single argument that is
# a heap element. Defaults to 1 [i.e. the identity operation]]>
# <[param pVal a <tt>lang::Closure</tt>, procedure, integer, or
# string-invocation implementing a comparison operation
# on the results of invoking fVal on two Heap elements.
# Defaults to "<"]>
#</p>
initially (S, fVal, pVal)
L := []
f := \fVal | 1
p := \pVal | "<"
every self.add(!\S)
end
This page produced by UniDoc on 2021/04/15 @ 23:59:43.