Sorts the elements in an array by its size using the Quicksort algorithm.
QSort x(s) [,n] [,m%()]
QSort x$(s) [Compare c][With n()] [,n [,m%()]]
s | : + or - for ascending or descending order |
c, n | : integer expression |
x() | : one dimensional floating point or integer array |
x$() | : one dimensional string array |
n() | : one dimensional integer array with 8-, 16- or 32-bit integer variables |
m%() | : one dimensional integer array with 32-bit integer variables |
The s enclosed in round brackets can be replaced with a "+", a "-" or may be left out. "+" or no specification results in arrays x() and m%() being sorted in ascending order. In this case, after the sorting, the smallest array element assumes the smallest index (0 for Option Base 0 or 1 for Option Base 1). "-" results in the array being sorted in descending order. In this case, after the sorting, the biggest array element assumes the smallest index.
The parameter n specifies that only the first n elements of the array should be sorted. For Option Base 0 these are the elements with indices 0 to "n"-1, and for Option Base 1 the elements with indices 1 to "n". If n is given explicitly, it can be followed by a Long integer array, which will be sorted together with the array x(), that is to say, each swap in array x() will also be performed in array m%(). This is particularly useful when the sorted array x() contains the sort key (for example the postal code), while other arrays contain additional information that must maintain the same order as the keys.
When sorting string arrays (x$()) a sort criterion can be specified with With, in the form of an array n() with at least 256 elements. If With is not given the normal ASCII table is used as the sort criterion.
Another option when sorting string arrays is to use Compare c: this allows you to specify different comparison methods locally - case sensitive or insensitive, the sorting of accented characters, etc. - without changing the global Mode Comapre setting. The comparison method is determined by the value entered in c which corresponds to the values used with Mode Compare so for a case sensitive search c = -1, for a case insensitive search with correct sorting of accented characters c = 1, and so on.
This first example shows a sort with a dependant array:
Local i%, n% = 3
Dim a(n%), b%(n%), c$(n%), d$(n%)
Restore m1 : For i% = 0 To n% : Read a(i%) : Next i%
m1: : Data 10,-3,5,21
Restore m2 : For i% = 0 To n% : Read c$(i%) : b%(i%) = i% : Next i%
m2: : Data A,B,C,D
Restore m3 : For i% = 0 To n% : Read d$(i%) : Next i%
m3: : Data Who,How,What,Where
OpenW # 1 : GraphMode , TRANSPARENT : Win_1.FontName = "Courier"
For i% = 0 To n%
Print Str$(a(i%), 5, 2)``
Print Str$(b%(i%), 5, 2)``
Print c$(i%)``
Print d$(i%)
Next i%
QSort a(), n%, b%()
For i% = 0 To n%
Print Str$(a(i%), 5, 2)``
Print Str$(b%(i%), 5, 2)``
Print c$(b%(i%))``
Print d$(b%(i%))
Next i%
Prints first of all (unsorted)
10.00 1.00 A Who
-3.00 2.00 B How
5.00 3.00 C What
20.00 4.00 D Where
then (sorted)
-3.00 2.00 B How
5.00 3.00 C What
10.00 1.00 A Who
20.00 4.00 D Where
This second example shows a sort using the With keyword:
// Create array to be sorted
Local a$() : Array a$() = "D"#10"H"#10"A"#10"z"#10"c"
// RUN 1: populate the With array d%() with character codes in descending order
Local d%(255), n% : For n% = 0 To 255 : d%(n%) = 255 - n% : Next n%
// Show the array to be sorted before the sort
For n% = 0 To 4 : Print a$(n%), : Next n% : Print
// Sort in descending order which, as d%() is also descending will result in an ascending sort by ANSI code
QSort a$(-) With d%()
// The result of the sort
For n% = 0 To 4 : Print a$(n%), : Next n% : Print
// RUN 2: populate the With array d%() with a 'Text' sort to ignore capital letters
Local b$ = " !" & #34 & "#$%&'()*+,-./0123456789:;<=>?@AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsߊTt" & _
"UuVvWwXxYyZz[\]^_`{|}~ "
For n% = 0 To 31 : d%(n%) = n% : Next n%
For n% = 32 To 255 : d%(n%) = Asc(Mid(b$, n% - 31, 1)) : Next n%
// Sort the array in ascending order
QSort a$(+) With d%(), 4 // <--- Without the 'count' variable, this does not work properly.
// And print the result
For n% = 0 To 4 : Print a$(n%), : Next n% : Print
The final example illustrates how to use of the Compare keyword:
Local Int32 m%(10), n%, x$(10)
For n% = 0 To 10 : m%(n%) = 10 - n% : Read x$(n%) : Next n%
// Descending Case Sensitive sort of the first 7 elements only
QSort x$(-) Compare -1, 7, m%()
For n% = 0 To 10 : Print n%, m%(n%), x$(n%) : Next n%
Data "A","c","D","e","f","J","K","m","N","p","Z"
Interestingly, running a sort with dependant array to be sorted at the same time seems to be quicker than if the the second array is omitted as the following code snippet shows:
Dim a$(120), a%(120), n%, t#
For n% = 1 To 120 : a$(n%) = Chr(65 + (Rnd * 26)) : a%(n%) = n% : Next n
t# = Timer
For n% = 1 To 10000
QSort a$()
Next n%
Print Timer - t#
t# = Timer
For n% = 1 To 10000
QSort a$(), 120, a%()
Next n%
Print Timer - t#
[Reported by James Gaite. 24/01/17]Using the With keyword can sometimes lead to inaccurate results: to see this, copy the second of the two examples and remove the count variable from the second QSort statement - the 'z' will now be ordered as the second character, not the last. Then replace the count variable and change the 'H' in the array to be sorted to 'h'; now 'h' is the second character listed.
A second problem can occur when using With if not all of the 256 ANSI values are included - this leads to results similar to those highlighted above.
General advice is not to use the With keyword unless necesary and use the Mode Compare settings where possible in its place.[Reported by James Gaite. 16/01/17 & 26/02/17]
If you sort a string array in descending order where all the strings are null or blank(""), then an Access-Violation Exception error message will be thrown. This does not happen if the sort is in ascending order.[Reported by James Gaite. 17/01/17 ]
{Created by Sjouke Hamstra; Last updated: 18/01/2022 by James Gaite; Other Contributors: Jean-Marie Melanson}