\ HeapSort in Forth assuming zero-based indexing -- v.1.0.1 \ Complexity: O(n*log(n)) \ (p) M.L.Gassanenko, 2000 \ Review and testing: Ruvim Pinka \ Public domain, NO WARRANTY \ "HeapSort" in Russian is called "pyramidal sort". \ ------------------------------------------------------------- \ To sort an array (assuming zero-based indexing), \ 1) specify: \ its size -- store to PyrN ( # of items in the array ) \ what "less than" means -- store to []<[] ( i j -- i j f ) \ how to exchange items -- store to []exch[] ( i j -- i j ) \ where 0<=iR 0 DUP BEGIN ( i i.old ) ( R: m ) DROP DUP leftrightbelow DUP R@ < WHILE ( i i.lb i.rb ) chooseMAX SWAP ( i.b i ) [min]exch[MAX]n? UNTIL ELSE R@ = IF ( i i.lb ) SWAP [min]exch[MAX]n? DROP THEN THEN ( i.lb i ) 2DROP R> ; : SortPyr ( -- ) PyrN ( m0) PyrN 1 DO ( m) 1- ( m) 0 []exch[] DROP ( m) TopGoesDown ( m) LOOP DROP ; \ --- the main word --- : HeapSort ( -- ) \ Uses: []<[] []exch[] PyrN PyrN 1 > IF ConstrPyr SortPyr THEN ; \ ---- only comments now ------------------------------------------------------ \ \ A pyramid is an array viewed like the following \ (digits show item numbers, not items!): \ \ 0 \ 1 2 \ 3 4 5 6 \ 7 8 9 a b c d e \ \ that is, the 0-th item is above the 1-st and 2-nd ones, \ the 1-st item is above 3-rd and 4-th, etc. \ \ Definition. An array is pyramidally ordered if each item is \ greater than or equal to the two items below it \ (if there are items below it, of course). \ \ Key to stack comments: \ i j k -- element #s \ i.a -- the element above i in the pyramid \ i.rb -- the right item below i in the pyramid \ i.lb -- the left item below i in the pyramid \ m -- # items in the yet unsorted part (m-th is the first in the sorted part) \ i.old -- i from the previous iteration \ \ The main idea. \ The pyramidal sort two times "bubble-sorts" each path from the "basement" \ to the "top". Each such step brings only one item to its place, but the \ number of items involved is at most [log2(n)] -- it's the number of layers. \ \ \ Definition: a "bubble run" is a series of exchanges of the sort \ this:=first; that:=nextto(this); \ while that<=last do \ if elem[this]