ShellSort

From Pickwiki
Revision as of 00:57, 13 February 2004 by Ian McGowan (talk) (Wrap in <PRE> tags)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search
* sort1 sorts a dynamic array by the requested delimiter
************************************************************************

      SUBROUTINE SORT1 (ARRAY, DELIM, SORTTYPE)

************************************************************************

* Modifications since date stamp
* ******************************

* None at present.
* 07/05/96 : Swap routine made much simpler and shorter. Rewrite done due
*            to a bug when sorting numbers left justified.

* NOTE
* ****

* awy Jun93 : This uses the Shell sort (named after Donald Shell at IBM)
*             It is a general-purpose, pretty efficient sort, and by
*             using matrices is quite fast. It works by comparing and
*             swapping if necessary items which are 'n' places apart.
*             'n' starts at half the total number of items and is halved
*             for each pass. This makes it an n-log(n) sort. There are a
*             variety of rules about how to 'tweak' it, but this version
*             is pretty crude.

      FIELDCOUNT = DCOUNT(ARRAY, DELIM)
      IF FIELDCOUNT LT 2 THEN RETURN    ;* No point sorting 0 or 1

* Convert dynamic array into matrix
      DIMENSION MATRIX(FIELDCOUNT)
      MATPARSE MATRIX FROM ARRAY, DELIM

* Set up ascend/descent, justify, and start interval
      AD = SORTTYPE[1,1]
      LR = SORTTYPE[2,1]
      INTERVAL = INT(FIELDCOUNT*0.5)

* Now to business - the outer LOOP continues until the swap interval
* has been through 1 to become zero. The inner FOR 'bubbles' each entry
* up as far as it will go by calling SWAP
      LOOP UNTIL INTERVAL EQ 0
         FOR BUBBLE = INTERVAL+1 TO FIELDCOUNT
            SWAPVAR = BUBBLE
            GOSUB SWAP:
         NEXT
         INTERVAL = INT(INTERVAL*0.5)
      REPEAT

* Now rebuild dynamic array and return
*     MATBUILD ARRAY FROM MATRIX USING DELIM ;* Doesn't work - infobasic bug
      MATBUILD ARRAY FROM MATRIX USING @IM
      CONVERT @IM TO DELIM IN ARRAY
      RETURN

********************************
* This simply compares the current entry with the entry INTERVAL before.
* If it is in the correct order, or the current entry is too close to the
* top it returns. Otherwise it swaps the two entries, and loops to see if
* it can move the current entry even higher.
SWAP:
      LOOP
         COMPVAR = SWAPVAR - INTERVAL
         IF COMPVAR LT 1 THEN RETURN

         IF LR EQ 'R'
            THEN COMPVALUE = COMPARE( MATRIX(SWAPVAR), MATRIX( COMPVAR), "R")
            ELSE COMPVALUE = COMPARE( MATRIX(SWAPVAR), MATRIX( COMPVAR), "L")
         IF AD EQ "D" THEN COMPVALUE = 0 - COMPVALUE

         IF COMPVALUE GE 0 THEN RETURN

         TEMP = MATRIX(COMPVAR)
         MATRIX(COMPVAR) = MATRIX(SWAPVAR)
         MATRIX(SWAPVAR) = TEMP
         SWAPVAR = COMPVAR

      REPEAT
   END