11-07-2004, 05:06 PM
Ok, here's my entry on this challenge. The algorithm used is a relatively simple Double Insertion Sort, upgraded from the normal Insertion Sort.
[syntax="QBasic"]'*- These are the declaration of the routines needed for Double Insertion Sort -*'
'*- For explanation of these routines refer to the routines themselves -*'
DECLARE SUB DoubleInsertionSort (Array() AS ANY)
DECLARE SUB ShiftDown (Array() AS ANY, FromPlace AS INTEGER, ToPlace AS INTEGER)
'*- Some standard conventions -*'
DEFINT A-Z
'$DYNAMIC
'*- The record we'll use -*'
TYPE Record
LASTNAME AS STRING * 10
AGE AS STRING * 2
END TYPE
'*- Create an array of 10 of these records -*'
DIM PersonData(9) AS Record
'*- Fill Array with Test Data -*'
PersonData(0).LASTNAME = "SMITH"
PersonData(0).AGE = "34"
PersonData(1).LASTNAME = "ANDERSON"
PersonData(1).AGE = "29"
PersonData(2).LASTNAME = "MYERSCOUGH"
PersonData(2).AGE = "18"
PersonData(3).LASTNAME = "RIETVELD"
PersonData(3).AGE = "18"
PersonData(4).LASTNAME = "SMITH"
PersonData(4).AGE = "22"
PersonData(5).LASTNAME = "ANDERSON"
PersonData(5).AGE = "35"
PersonData(6).LASTNAME = "SMITH"
PersonData(6).AGE = "99"
PersonData(7).LASTNAME = "RIETVELD"
PersonData(7).AGE = "74"
PersonData(8).LASTNAME = "SMITH"
PersonData(8).AGE = "88"
PersonData(9).LASTNAME = "ANDERSON"
PersonData(9).AGE = "34"
'*- Print out data before sorting -*'
FOR I = LBOUND(PersonData) TO UBOUND(PersonData)
PRINT PersonData(I).LASTNAME, PersonData(I).AGE
NEXT I
'*- To separate both lists -*'
PRINT
'*- Sort the array -*'
CALL DoubleInsertionSort( PersonData() )
'*- Print out data after sorting -*'
FOR I = LBOUND(PersonData) TO UBOUND(PersonData)
PRINT PersonData(I).LASTNAME, PersonData(I).AGE
NEXT I
'*- Exit the program -*'
SUB DoubleInsertionSort (Array() AS Record)
'+--------------------------------------------------------------+'
'| SUB DoubleInsertionSort (Array() AS Record) |'
'| |'
'| This routine sorts the Array passed to this function. The |'
'| sort algorithm will first sort on LASTNAME, then on AGE. |'
'| All in one run. Respectively ascending and descending. |'
'| The algorithm is a relatively simple Double Insertion Sort |'
'| upgraded from the normal Insertion Sort. |'
'| It's not the fastest algorithm available, but it works. |'
'| |'
'| NOTE: Arrays of any size can be passed to this function, as |'
'| long as they are one-dimensional and declared of type |'
'| "Record". |'
'| |'
'| Neo |'
'+--------------------------------------------------------------+'
'*- Get the upper and lower bound to prevent repetitive calls -*'
lowbound% = LBOUND(Array)
upbound% = UBOUND(Array)
'*- The outer loop determines which data is to be sorted -*'
FOR dataloop = lowbound% TO upbound%
'*- A variable which indicates when the insertion place has been reached -*'
StillFits% = -1
'*- To prevent repetitive calls to RTRIM$ and VAL -*'
tmplastname$ = RTRIM$(Array(dataloop).LASTNAME)
tmpage% = VAL(RTRIM$(Array(dataloop).AGE))
'*- The inner loop scans all possible places for the data to be sorted -*'
FOR findloop = lowbound% TO dataloop - 1
'*- To prevent repetitive calls to RTRIM$ and VAL -*'
tmplastname2$ = RTRIM$(Array(findloop).LASTNAME)
tmpage2% = VAL(RTRIM$(Array(findloop).AGE))
'*- Check whether this place is suitable for the data -*'
IF tmplastname2$ > tmplastname$ THEN
StillFits = 0
ELSEIF tmplastname2$ = tmplastname$ AND tmpage2% < tmpage% THEN
StillFits = 0
END IF
'*- If it's suitable insert the data here and stop the inner loop -*'
IF NOT StillFits THEN
ShiftDown Array(), findloop, dataloop
EXIT FOR
END IF
NEXT findloop
NEXT dataloop
END SUB
SUB ShiftDown (Array() AS Record, FromPlace AS INTEGER, ToPlace AS INTEGER)
'+--------------------------------------------------------------+'
'| SUB ShiftDown (Array() AS Record, FromPlace%, ToPlace%) |'
'| |'
'| This routine shifts a part of the record array down to make |'
'| place for the data which is to be inserted at the beginning. |'
'+--------------------------------------------------------------+'
FOR shiftloop = ToPlace TO FromPlace + 1 STEP -1
SWAP Array(shiftloop), Array(shiftloop - 1)
NEXT shiftloop
END SUB[/syntax]
[syntax="QBasic"]'*- These are the declaration of the routines needed for Double Insertion Sort -*'
'*- For explanation of these routines refer to the routines themselves -*'
DECLARE SUB DoubleInsertionSort (Array() AS ANY)
DECLARE SUB ShiftDown (Array() AS ANY, FromPlace AS INTEGER, ToPlace AS INTEGER)
'*- Some standard conventions -*'
DEFINT A-Z
'$DYNAMIC
'*- The record we'll use -*'
TYPE Record
LASTNAME AS STRING * 10
AGE AS STRING * 2
END TYPE
'*- Create an array of 10 of these records -*'
DIM PersonData(9) AS Record
'*- Fill Array with Test Data -*'
PersonData(0).LASTNAME = "SMITH"
PersonData(0).AGE = "34"
PersonData(1).LASTNAME = "ANDERSON"
PersonData(1).AGE = "29"
PersonData(2).LASTNAME = "MYERSCOUGH"
PersonData(2).AGE = "18"
PersonData(3).LASTNAME = "RIETVELD"
PersonData(3).AGE = "18"
PersonData(4).LASTNAME = "SMITH"
PersonData(4).AGE = "22"
PersonData(5).LASTNAME = "ANDERSON"
PersonData(5).AGE = "35"
PersonData(6).LASTNAME = "SMITH"
PersonData(6).AGE = "99"
PersonData(7).LASTNAME = "RIETVELD"
PersonData(7).AGE = "74"
PersonData(8).LASTNAME = "SMITH"
PersonData(8).AGE = "88"
PersonData(9).LASTNAME = "ANDERSON"
PersonData(9).AGE = "34"
'*- Print out data before sorting -*'
FOR I = LBOUND(PersonData) TO UBOUND(PersonData)
PRINT PersonData(I).LASTNAME, PersonData(I).AGE
NEXT I
'*- To separate both lists -*'
'*- Sort the array -*'
CALL DoubleInsertionSort( PersonData() )
'*- Print out data after sorting -*'
FOR I = LBOUND(PersonData) TO UBOUND(PersonData)
PRINT PersonData(I).LASTNAME, PersonData(I).AGE
NEXT I
'*- Exit the program -*'
SUB DoubleInsertionSort (Array() AS Record)
'+--------------------------------------------------------------+'
'| SUB DoubleInsertionSort (Array() AS Record) |'
'| |'
'| This routine sorts the Array passed to this function. The |'
'| sort algorithm will first sort on LASTNAME, then on AGE. |'
'| All in one run. Respectively ascending and descending. |'
'| The algorithm is a relatively simple Double Insertion Sort |'
'| upgraded from the normal Insertion Sort. |'
'| It's not the fastest algorithm available, but it works. |'
'| |'
'| NOTE: Arrays of any size can be passed to this function, as |'
'| long as they are one-dimensional and declared of type |'
'| "Record". |'
'| |'
'| Neo |'
'+--------------------------------------------------------------+'
'*- Get the upper and lower bound to prevent repetitive calls -*'
lowbound% = LBOUND(Array)
upbound% = UBOUND(Array)
'*- The outer loop determines which data is to be sorted -*'
FOR dataloop = lowbound% TO upbound%
'*- A variable which indicates when the insertion place has been reached -*'
StillFits% = -1
'*- To prevent repetitive calls to RTRIM$ and VAL -*'
tmplastname$ = RTRIM$(Array(dataloop).LASTNAME)
tmpage% = VAL(RTRIM$(Array(dataloop).AGE))
'*- The inner loop scans all possible places for the data to be sorted -*'
FOR findloop = lowbound% TO dataloop - 1
'*- To prevent repetitive calls to RTRIM$ and VAL -*'
tmplastname2$ = RTRIM$(Array(findloop).LASTNAME)
tmpage2% = VAL(RTRIM$(Array(findloop).AGE))
'*- Check whether this place is suitable for the data -*'
IF tmplastname2$ > tmplastname$ THEN
StillFits = 0
ELSEIF tmplastname2$ = tmplastname$ AND tmpage2% < tmpage% THEN
StillFits = 0
END IF
'*- If it's suitable insert the data here and stop the inner loop -*'
IF NOT StillFits THEN
ShiftDown Array(), findloop, dataloop
EXIT FOR
END IF
NEXT findloop
NEXT dataloop
END SUB
SUB ShiftDown (Array() AS Record, FromPlace AS INTEGER, ToPlace AS INTEGER)
'+--------------------------------------------------------------+'
'| SUB ShiftDown (Array() AS Record, FromPlace%, ToPlace%) |'
'| |'
'| This routine shifts a part of the record array down to make |'
'| place for the data which is to be inserted at the beginning. |'
'+--------------------------------------------------------------+'
FOR shiftloop = ToPlace TO FromPlace + 1 STEP -1
SWAP Array(shiftloop), Array(shiftloop - 1)
NEXT shiftloop
END SUB[/syntax]