[Date Prev] [Date Next] [Thread Prev] [Thread Next] Date Index Thread Index Search archive:
Date:Mon Sep 3 10:07:15 1993 
Subject:Re: Insertion sort in Pop 
From:Robin Popplestone 
Volume-ID:930903.05 

   Ruvan Weerasinghe writes in <1993Sep2.115134.18560@cm.cf.ac.uk>

>    Does anyone have code for this - or what is the best way to do such a
>    sort from prolog? (My problem is that I have random numbers (say) coming
>    in 'asynchronously' which I need to place in order so that I can 'pop'
>    off the highest from the 'top' of the 'stack' at any time... while
>    numbers still keep coming in).


Assuming that POP-11's syssort does not provide the performance you
need (i.e. you can't just cons on each new number and then sort the list
of all numbers) then the best solution would seem to be some kind
of tree sort. If the numbers are truly random, then you may not have
to worry about keeping the tree balanced.

Below is a solution. It allows the same number to be inserted multiple
times into the sort tree. It suffers from the snags:

(a) It is constructive, so takes an expected space-turn-over of log(n)
per insertion

(b) No attempt is made to keep the tree balanced, so if you give it a
pessimal sequence of insertions (an input list sorted in the wrong order
I think) it will take time n to make an insertion.

(c) "dead" nodes, with multiplicity 0, are left around.

See any book on algorithms about how to do better.

/*

         CONTENTS - (Use <ENTER> g to access required sections)

 --  A _node in a sorted tree holds a value, and left and right sub-trees.
 --  insert(x,tree,f) inserts the value x in the sort-tree, comparison is f
 --  first(tree)->(x,tree_1) plucks the lowest value from a tree
 --  Example of use of insert, first


*/

/*
A _node in a sorted tree holds a value, and left and right sub-trees.
--------------------------------------------------------------------
*/

defclass _node
  {val,    ;;; The value stored in this node
   mult,   ;;; Its "multiplicity" - how often it has been put in
   left,   ;;; The sub-tree of values preceding  -val-
   right}; ;;; The sub-trees of values following -val-

/*
insert(x,tree,f) inserts the value x in the sort-tree, comparison is f
----------------------------------------------------------------------
*/

define insert(x,tree,f);
    lvars x,tree;
    if tree then
        lvars (v,m,l,r) = dest_node(tree);
        if x=v then  cons_node(v,m+1,l,r)
        elseif f(x,v) then cons_node(v,m,insert(x,l,f),r);
        else cons_node(v,m,l,insert(x,r,f))
        endif
    else cons_node(x,1,false,false)
    endif;
enddefine;

/*
first(tree)->(x,tree_1) plucks the lowest value from a tree
------------------------------------------------------------
*/

define first(tree);
    if is_node(tree) then
        lvars (v,m,l,r) = dest_node(tree);
        lvars(x,tree_1) = first(l);
        if tree_1 then (x,cons_node(v,m,tree_1,r))
        elseif m>0 then (v, cons_node(v,m-1,l,r))
        else first(r)
        endif;
    else
        (undef,false)
    endif;
enddefine;


/*
Example of use of insert, first
-------------------------------
This example does all insertions followed by deletions, but
you can in fact interleave them I hope.
  comment this out if you don't have the example macro available
  */
  example insert

vars procedure( insert1 = insert(%nonop < %), );

vars x, tree = false;
for x in [2 3 4 1 5 4 7] do insert1(x,tree)->tree; endfor;
vars List = [%while tree do first(tree) -> (x,tree); x; endwhile%];
List =>
** [1 2 3 4 4 5 7 undef]
endexample


Robin Popplestone.