BeeJ
9/9/2011 10:07:00 PM
The code below is what I mean by a "pointer" swap sort.
I have already, months ago, looked at all the references given so far
and none do a "pointer" swap sort on a UDT, AFAIK.
I have tried the parallel index swap sort for strings and have also
written a UDT sort that swaps each item (i.e. copy to sTemp, sTemp to
....) and it is fairly fast but not what I hoped for. I will study what
Nobody presented in his two recent posts.
' =========================================================
Private Declare Function ArrPtr Lib "msvbvm60" Alias "VarPtr" (Ptr() As
Any) As Long
Private Declare Sub RtlMoveMemory Lib "kernel32" (Dst As Any, Src As
Any, ByVal cb As Long)
Public Sub QSort(asArray() As DataType)
' QSort String-Arrays
Dim lIXx As Long
Dim lIXy As Long
Dim lPtrLo As Long
Dim lPtrHi As Long
Dim lPtrStr As Long
Dim lPtr As Long
Dim lStSize As Long
Dim asV(0) As String
Dim alpV() As Long
Dim alsapV(5) As Long
Dim alPArr() As Long
Dim alsaPArr(5) As Long
Dim alStLo() As Long
Dim alStHi() As Long
lStSize = 255
ReDim alStLo(lStSize)
ReDim alStHi(lStSize)
alsaPArr(0) = 1
alsaPArr(1) = 4 ' initialize StrPtr-Arrays for fast swap
alsaPArr(3) = VarPtr(asArray(0))
alsaPArr(4) = UBound(asArray) + 1
RtlMoveMemory ByVal ArrPtr(alPArr), VarPtr(alsaPArr(0)), 4
'
alsapV(0) = 1
alsapV(1) = 4
alsapV(3) = VarPtr(asV(0))
alsapV(4) = 1
RtlMoveMemory ByVal ArrPtr(alpV), VarPtr(alsapV(0)), 4
alStLo(0) = LBound(asArray)
alStHi(0) = UBound(asArray)
lPtrStr = 1
Do
lPtrStr = lPtrStr - 1
lPtrLo = alStLo(lPtrStr)
lPtrHi = alStHi(lPtrStr)
If lPtrHi - lPtrLo < 12 Then '
For lPtrLo = lPtrLo To lPtrHi - 1
lIXy = lPtrLo
For lIXx = lPtrLo + 1 To lPtrHi
If asArray(lIXx).sKey < asArray(lIXy).sKey Then
lIXy = lIXx
End If
Next lIXx
If lIXy <> lPtrLo Then
lPtr = alPArr(lIXy)
alPArr(lIXy) = alPArr(lPtrLo)
alPArr(lPtrLo) = lPtr
End If
Next lPtrLo
Else 'QSort
Do
lIXx = lPtrLo
lIXy = lPtrHi
alpV(0) = alPArr((lPtrLo + lPtrHi) \ 2)
Do
Do While asArray(lIXx).sKey < asV(0)
lIXx = lIXx + 1
Loop
Do While asArray(lIXy).sKey > asV(0)
lIXy = lIXy - 1
Loop
If lIXx <= lIXy Then
lPtr = alPArr(lIXx)
alPArr(lIXx) = alPArr(lIXy)
alPArr(lIXy) = lPtr
lIXx = lIXx + 1
lIXy = lIXy - 1
End If
Loop While lIXx <= lIXy
If lIXy - lPtrLo < lPtrHi - lIXx Then
If lIXx < lPtrHi Then
alStLo(lPtrStr) = lIXx
alStHi(lPtrStr) = lPtrHi
lPtrStr = lPtrStr + 1
If lPtrStr >= lStSize Then
lStSize = lStSize + lStSize
ReDim Preserve alStLo(lStSize)
ReDim Preserve alStHi(lStSize)
End If
End If
lPtrHi = lIXy
Else
If lPtrLo < lIXy Then
alStLo(lPtrStr) = lPtrLo
alStHi(lPtrStr) = lIXy
lPtrStr = lPtrStr + 1
If lPtrStr >= lStSize Then
lStSize = lStSize + lStSize
ReDim Preserve alStLo(lStSize)
ReDim Preserve alStHi(lStSize)
End If
End If
lPtrLo = lIXx
End If
Loop While lPtrLo < lPtrHi
End If
Loop While lPtrStr
RtlMoveMemory ByVal ArrPtr(alPArr), 0&, 4
alpV(0) = 0
RtlMoveMemory ByVal ArrPtr(alpV), 0&, 4
End Sub 'QSort
' =========================================================