[futurebasic] Re: Quicksort For Numbers

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : June 1999 : Group Archive : Group : All Groups

From: Ian Mann <i.mann@...>
Date: Thu, 10 Jun 1999 10:28:29 +0000
Attached is snippet that I use to sort scrolling lists. The only bit I
think you want is the Select case _ColIsNumber.

FindArray% is the listing of items selected by the last searches.

SortArray% is an array holding the item order. I tend not to mess with
the actual order as I may want to stick individual things back in a file
record.

CLEAR LOCAL
DIM SortStack%(30,1),SortPoint%,LeftPointer%,RightPointer%
DIM LeftIndex%,RightIndex%,MidValue%
LOCAL FN QuickSort (WndNum%,cNum%,Col%)
  CPtr& = [wData.wCtrlHndl&(WndNum%)] + _ContRecLen * cNum%
  ScrPtr& = [CPtr&.ContHndl&]
  ScrPtr&.sSortCol% = Col%
  gColArray& = ScrPtr&.sColHandle&
  gFindArray& = ScrPtr&.sFindHandle&
  gSortArray& = ScrPtr&.sSortHandle&
  DataPtr& = [ScrPtr&.sDataHandle&]
  fc% = gColArray.ColFirstChar%(Col%)
  mc% = gColArray.ColMaxChar%(Col%)
  FOR Counter% = 0 TO ScrPtr&.sNumFound%
    gSortArray%(Counter%) = Counter%
  NEXT
  SortPoint% = 0
  SortStack%(0,0) = 0
  SortStack%(0,1) = ScrPtr&.sNumFound%
  DO
    LeftPointer% = SortStack%(SortPoint%,0)
    RightPointer% = SortStack%(SortPoint%,1)
    DEC(SortPoint%)
    DO
      LeftIndex% = LeftPointer%
      RightIndex% = RightPointer%
      APtr& = DataPtr& + gFindArray%(gSortArray%((LeftPointer% +
RightPointer%) / 2)) * _ScrStrRecLen
      a$ = UCASE$(MID$(APtr&.ScrData$,fc%,mc%))
      ANum# = VAL (a$)
      DO
        SELECT CASE gColArray.ColDataType% (Col%)
          CASE _ColIsString
            APtr& = DataPtr& + gFindArray%(gSortArray%(LeftIndex%)) *
_ScrStrRecLen
            WHILE UCASE$(MID$(APtr&.ScrData$,fc%,mc%)) < a$
              INC(LeftIndex%)
              APtr& = DataPtr& + gFindArray%(gSortArray%(LeftIndex%)) *
_ScrStrRecLen
            WEND
            '
            APtr& = DataPtr& + gFindArray%(gSortArray%(RightIndex%)) *
_ScrStrRecLen
            WHILE UCASE$(MID$(APtr&.ScrData$,fc%,mc%)) > a$
              DEC(RightIndex%)
              APtr& = DataPtr& + gFindArray%(gSortArray%(RightIndex%)) *
_ScrStrRecLen
            WEND
            '
          CASE _ColIsNumber
            APtr& = DataPtr& + gFindArray%(gSortArray%(LeftIndex%)) *
_ScrStrRecLen
            WHILE VAL(MID$(APtr&.ScrData$,fc%,mc%)) < ANum#
              INC(LeftIndex%)
              APtr& = DataPtr& + gFindArray%(gSortArray%(LeftIndex%)) *
_ScrStrRecLen
            WEND
            '
            APtr& = DataPtr& + gFindArray%(gSortArray%(RightIndex%)) *
_ScrStrRecLen
            WHILE VAL(MID$(APtr&.ScrData$,fc%,mc%)) > ANum#
              DEC(RightIndex%)
              APtr& = DataPtr& + gFindArray%(gSortArray%(RightIndex%)) *
_ScrStrRecLen
            WEND

        END SELECT

        LONG IF LeftIndex% <= RightIndex%
          SWAP gSortArray%(LeftIndex%),gSortArray%(RightIndex%)
          INC(LeftIndex%)
          DEC(RightIndex%)
        END IF
      UNTIL LeftIndex% > RightIndex%
      '
      LONG IF (RightPointer% - LeftIndex%) > (RightIndex% -
LeftPointer%)
        LONG IF LeftPointer% < RightIndex%
          INC(SortPoint%)
          SortStack%(SortPoint%,0) = LeftPointer%
          SortStack%(SortPoint%,1) = RightIndex%
        END IF
        LeftPointer% = LeftIndex%
      XELSE
        LONG IF LeftIndex% < RightPointer%
          INC(SortPoint%)
          SortStack%(SortPoint%,0) = LeftIndex%
          SortStack%(SortPoint%,1) = RightPointer%
        END IF
        RightPointer% = RightIndex%
      END IF
    UNTIL RightPointer% <= LeftPointer%
  UNTIL SortPoint% = -1
  FN FindSelection (WndNum%,cNum%)
  FN GenRefresh (WndNum%,cNum%,cNum%,_True,0)
END FN

Let me know if this is unclear.

Regards

Ian Mann