Source file pqueue.icn
############################################################################
#
#       File:     pqueue.icn
#
#       Subject:  Class MaxPQueue, implementing a max-priority queue.
#                 Also see Steve Wampler's more general priority queue.
#
#       Authors:  Kostas Oikonomou
#                 Based on pqueue.icn in the IPL, by William S. Evans and
#                 Gregg M. Townsend.
#
#       Date:     September 15, 2004
#
############################################################################
#
#   This file is in the public domain.
#
############################################################################
#
#       Methods:
#
#	construct(S)	returns a max-priority queue containing the elements
#			in  the structure (list, table, or set) S of "elem"
#                       records, each containing a "data" and a numeric
#                       "priority" field.
#
#	get()	        removes and returns the highest priority element
#			from the priority queue.
#
#	put(e)	        adds element e (a "elem" record) to the queue.
#
#	gen()	        generates (non-destructively) the elements of the queue
#                       in order, highest priority first.
#
#       len()           returns the number of elements in the queue.
#       maxlen()        returns the maximum length reached by the queue during
#                       its lifetime.
#
#	elem(d, p)	constructs a record with data d and priority p.
#
#
############################################################################
#
#	The priority queue is implemented as a max-heap.  The heap is
#	implemented by a list in the usual fashion.
#
############################################################################

class MaxPQueue(Q, elem, L)

  # Create the queue from a list, table, or set of "elem"
  method construct(S)	
    local i
    /S := list()
    Q := list()
    every self.put(!S)
    every down(i := *Q/2 to 1 by -1)
    L := *Q
    return
  end

  # Queue length and maximum length
  method len()
    return *Q
  end
  method maxlen()
    return L
  end

  # Remove first element
  method get()
    local e
    e := ::get(Q) | fail  # this is Icon's ordinary "get"
    push(Q, pull(Q))
    down(1)
    L <:= *Q
    return e
  end

  # Insert element
  method put(e)
    ::put(Q, e)           # this is Icon's ordinary "put"
    up(*Q)
    L <:= *Q
    return
  end

  # Generate the elements
  method gen()	
    local q, e
    q := copy(Q)
    while e := copy(self.get(q)) do
      suspend e
  end


  method down(i)
    local left, right, largest
    left := i * 2
    right := left + 1
    if Q[left].priority > Q[i].priority then
      largest := left
    else 
      largest := i
    if Q[right].priority > Q[largest].priority then largest := right
    if largest ~= i then {
      Q[i] :=: Q[largest]
      down(largest)
    }
    return
  end

  method up(i)
    local parent
    parent := i/2
    if Q[i].priority > Q[parent].priority then {
      Q[i] :=: Q[parent]
      up(parent)
    }
    return
  end


  initially
    elem := constructor("elem", "data", "priority")
    Q := []
    L := 0

end

This page produced by UniDoc on 2021/04/15 @ 23:59:43.