Dim S1(L To R) As Strings Dim B1(1 To nChars) As Byte Dim P1(L To R) As Long
For I = L To R S1(I) = GetRandomString() Next I
StrsToBytes S1, L, R, B1, P1
TernaryQuickSort L, R, B1, P1
Sub TernaryQuickSort(L As Long, R As Long, B() As Byte, P() As Long) TernQuick L, R, B, P, 0 End Sub
Sub TernQuick(L As Long, R As Long, B() As Byte, P() As Long, _ ByVal DEPTH As Integer) Dim TMP As Long Dim I As Long Dim J As Long Dim pMED As Long Dim Pivot As Integer Dim OuterL As Long Dim InnerL As Long Dim InnerR As Long Dim OuterR As Long Dim DIF As Long Dim N As Long Dim SwapN As Long Dim NLO As Long Dim NHI As Long Dim NEQ As Long
N = 1 + R - L If N > 10 Then pMED = BGetMed(B, P, L, N, DEPTH) TMP = P(L) P(L) = P(pMED) P(pMED) = TMP Pivot = B(P(L) + DEPTH) OuterL = L InnerL = OuterL OuterR = R InnerR = OuterR Do Do While InnerL <= InnerR DIF = B(P(InnerL) + DEPTH) - Pivot If DIF > 0 Then Exit Do If DIF = 0 Then TMP = P(OuterL) P(OuterL) = P(InnerL) P(InnerL) = TMP OuterL = OuterL + 1 End If InnerL = InnerL + 1 Loop Do While InnerL <= InnerR DIF = B(P(InnerR) + DEPTH) - Pivot If DIF < 0 Then Exit Do If DIF = 0 Then TMP = P(OuterR) P(OuterR) = P(InnerR) P(InnerR) = TMP OuterR = OuterR - 1 End If InnerR = InnerR - 1 Loop If InnerL > InnerR Then Exit Do TMP = P(InnerL) P(InnerL) = P(InnerR) P(InnerR) = TMP InnerL = InnerL + 1 InnerR = InnerR - 1 Loop NLO = InnerL - OuterL NHI = OuterR - InnerR NEQ = N - (NLO + NHI) If OuterL - L < NLO Then SwapN = OuterL - L Else SwapN = NLO I = L J = InnerL - SwapN Do While SwapN > 0 TMP = P(I) P(I) = P(J) P(J) = TMP I = I + 1 J = J + 1 SwapN = SwapN - 1 Loop If R - OuterR < NHI Then SwapN = R - OuterR Else SwapN = NHI I = InnerL J = R + 1 - SwapN Do While SwapN > 0 TMP = P(I) P(I) = P(J) P(J) = TMP I = I + 1 J = J + 1 SwapN = SwapN - 1 Loop If B(P(L+NLO) + DEPTH) <> 0 Then TernQuick L+NLO, L+NLO+NEQ-1, B, P, _ DEPTH+1 If NLO < NHI Then TernQuick L, L + NLO - 1, B, P, DEPTH TernQuick L + NLO + NEQ, L + NLO + NEQ + NHI - 1, B, P, DEPTH Else TernQuick L + NLO + NEQ, L + NLO + NEQ + NHI - 1, B, P, DEPTH TernQuick L, L + NLO - 1, B, P, DEPTH End If Else DeepInsertS B, P, L, N, DEPTH End If End Sub
Function BGetMed(B() As Byte, P() As Long, L As Long, N As Long, _ DEPTH As Integer) As Long Dim D As Long Dim PL As Long Dim PM As Long Dim PN As Long
PL = L PN = L + N - 1 PM = (PL + PN) \ 2 If N > 30 Then D = N \ 8 PL = BMed3(B, P, PL, PL + D, PL + 2 * D, DEPTH) PM = BMed3(B, P, PM - D, PM, PM + D, DEPTH) PL = BMed3(B, P, PN - 2 * D, PN - D, PN, DEPTH) End If BGetMed = BMed3(B, P, PL, PM, PN, DEPTH) End Function
Function BMed3(B() As Byte, P() As Long, I As Long, J As Long, K As Long, _ DEPTH As Integer) As Long Dim CI As Byte Dim CJ As Byte Dim CK As Byte CI = B(P(I) + DEPTH) CJ = B(P(J) + DEPTH) CK = B(P(K) + DEPTH) If (CI <= CJ And CJ <= CK) Or (CI >= CJ And CJ >= CK) Then BMed3 = J ElseIf (CJ <= CI And CI <= CK) Or (CJ >= CI And CI >= CK) Then BMed3 = I ElseIf (CI <= CK And CK <= CJ) Or (CI >= CK And CK >= CJ) Then BMed3 = K End If End Function
Sub DeepInsertS(B() As Byte, P() As Long, L As Long, N As Long, D As Integer) Dim LP As Long Dim RP As Long Dim TMP As Long Dim I As Long Dim J As Long For RP = L + 1 To L + N - 1 TMP = P(RP) For LP = RP To L + 1 Step -1 I = TMP + D J = P(LP - 1) + D Do While B(I) = B(J) If B(I) = 0 Or B(J) = 0 Then Exit Do I = I + 1 J = J + 1 Loop If CInt(B(I)) - CInt(B(J)) < 0 Then P(LP) = P(LP - 1) Else Exit For Next LP P(LP) = TMP Next RP End Sub
Sub Strs2Bytes(A() As String, L As Long, R As Long, B() As Byte, P() As Long) Dim I As Long Dim nPtrs As Long Dim nBytes As Long Dim DEPTH As Integer nBytes = 0 nPtrs = 0 For I = L To R nBytes = nBytes + Strings.Len(A(I)) + 1 nPtrs = nPtrs + 1 Next I ReDim B(1 To nBytes) ReDim P(1 To nPtrs) nPtrs = 1 nBytes = 1 For I = L To R P(nPtrs) = nBytes For DEPTH = 1 To Strings.Len(A(I)) B(nBytes) = Asc(Strings.MID(A(I), DEPTH, 1)) nBytes = nBytes + 1 Next DEPTH B(nBytes) = 0 nBytes = nBytes + 1 nPtrs = nPtrs + 1 Next I End Sub |