About the pivot:
If the array is already sorted, using the first element as the pivot will result in as many loops as a bubble sort. (i.e. slow). If the array is almost sorted, using pivot choosing to select the middle element as the pivot will be much faster. But that calculation slows things down a tiny bit.
If the use is user enters a list > sort > user adds to list > sort again, the time savings from pivot choosing is worth it.
If the use is to sort a random list once, pivot choosing is a minor time hit, and not needed.
Below is my version of a Quick Sort (perhaps not strictly a quick sort). It does not use recursion, but sorts the array in place.
QuickSortArray is a sub that will sort an array. QuickSortedArray is a function that, given an unsorted array, will return a sorted array.
Note the optional Descending argument.
Dim Stack() As Long
Dim StackPointer As Long
Sub test()
Dim x As Long, y As Long
Dim unsArray As Variant, sArray As Variant
unsArray = Array(2, 3, 4, 1, 34, 18, -34)
sArray = QuickSortedArray(unsArray, True)
MsgBox "unsorted: " & Join(unsArray) & vbCr & " sorted : " & Join(sArray)
End Sub
Function QuickSortedArray(ByRef unsortedArray, Optional Descending As Boolean) As Variant
Dim Result As Variant
Result = unsortedArray
QuickSortArray Result, Descending
QuickSortedArray = Result
End Function
Sub QuickSortArray(ByRef SortArray As Variant, Optional Descending As Boolean)
Dim Pivot As Variant, PivotPlace As Long
Dim Low As Long, High As Long
Dim i As Long, temp As Variant
StackPointer = 0
Push LBound(SortArray), UBound(SortArray)
Do Until StackPointer <= 0
Pop Low, High
Rem optional code for pivot choosing
i = (Low + High) / 2
temp = SortArray(i)
SortArray(i) = SortArray(High)
SortArray(High) = temp
Rem end pivot choosing
Pivot = SortArray(High)
PivotPlace = Low
For i = Low To High - 1
If (SortArray(i) < Pivot) Xor Descending Then
temp = SortArray(i)
SortArray(i) = SortArray(PivotPlace)
SortArray(PivotPlace) = temp
PivotPlace = PivotPlace + 1
End If
Next i
SortArray(High) = SortArray(PivotPlace)
SortArray(PivotPlace) = Pivot
If Low < PivotPlace Then Push Low, PivotPlace - 1
If PivotPlace < High Then Push PivotPlace + 1, High
Loop
End Sub
Sub Push(a As Long, b As Long)
On Error GoTo MakeStack
StackPointer = StackPointer + 1
If UBound(Stack, 2) < StackPointer Then ReDim Preserve Stack(1 To 2, 1 To 2 * StackPointer)
Stack(1, StackPointer) = a
Stack(2, StackPointer) = b
Exit Sub
MakeStack:
ReDim Stack(1 To 2, 1 To 1)
Err.Clear
Resume
End Sub
Function Pop(ByRef a As Long, ByRef b As Long) As Boolean
If StackPointer <= 0 Then
Pop = False
Else
a = Stack(1, StackPointer)
b = Stack(2, StackPointer)
Pop = True
End If
StackPointer = StackPointer - 1
End Function