|
楼主 |
发表于 2020-7-22 20:25
|
显示全部楼层
【插入法】比冒泡法速度快,但对逆向的数据,就是一个悲剧。
【快速排序法】,对顺序或逆序数据,都是个悲剧!
我只好自己写了个【二分法】先进行粗略排序。
目前的排序算法顺序:
1、先用快速排序法,如果快速排序法掉坑里了,调用【插入法】。
2、【插入法】检测数据量大,就先用【二分法】粗略排序(有限次数)。
3、【二分法】每次排序前,先检查数据是否已经完成排序,已经完成就跳出去了!
代码:
Private Function InsertSort(Arr() As Long, Operator As Boolean, Optional ByVal low As Variant = Null, Optional ByVal high As Variant = Null) '插入算法
Dim MinI As Long, MaxI As Long
If VBA.IsNull(low) Then
MinI = LBound(Arr)
Else
MinI = low
End If
If VBA.IsNull(high) Then
MaxI = UBound(Arr)
Else
MaxI = high
End If
If MinI >= MaxI Then Exit Function '1个元素
Dim i As Long
i = MaxI - MinI
If i > 100 Then '利用二分算法 粗略排序
i = Int(i ^ (1 / 3)) '开3次方
Call DichotomySort(Arr(), MinI, MaxI, Operator, i) '二分算法
End If
Dim Tmp As Long '临时变量
Dim PreI As Long '插入指针
For i = MinI + 1 To MaxI
Tmp = Arr(i)
PreI = i - 1
Do While PreI >= MinI
If Operator Then
If Not SortCArr_(Arr(PreI)) < SortCArr_(Tmp) Then Exit Do
Else
If Not SortCArr_(Arr(PreI)) > SortCArr_(Tmp) Then Exit Do
End If
Arr(PreI + 1) = Arr(PreI) '数据右移
PreI = PreI - 1 '指针左移
Loop
Arr(PreI + 1) = Tmp '插入
Next i
End Function
Private Function DichotomySort(Arr() As Long, ByVal low As Long, ByVal high As Long, Operator As Boolean, Optional ByVal Depth As Long = 0) As Long '二分法排序(粗略排序)
'Depth 深度计,<=0 退出
If low >= high Then Exit Function
If ScanSort(Arr, low, high, Operator) Then '检查排序
Exit Function
End If
If (high - low) < 10 Then
InsertSort Arr, Operator, low, high
Exit Function
End If
On Error GoTo Err1
Dim l As Long, h As Long, js As Long, LoopJs As Long, Str As String
Do While True
LoopJs = LoopJs + 1
l = low
h = high
js = 0
Do While l < h
Str = "A"
If Operator Then
If Not SortCArr_(Arr(l)) < SortCArr_(Arr(h)) Then GoTo Loop1
Else
If Not SortCArr_(Arr(l)) > SortCArr_(Arr(h)) Then GoTo Loop1
End If
swap Arr, l, h
js = js + 1
Loop1:
l = l + 1
h = h - 1
Loop
DichotomySort = l
l = low
Do While l < h And h <= high
Str = "B"
If Operator Then
If Not SortCArr_(Arr(l)) < SortCArr_(Arr(h)) Then GoTo Loop2
Else
If Not SortCArr_(Arr(l)) > SortCArr_(Arr(h)) Then GoTo Loop2
End If
swap Arr, l, h
js = js + 1
Loop2:
l = l + 1
h = h + 1
Loop
If js = 0 Then Exit Do
Loop
If high - low <= 2 Then Exit Function
Depth = Depth - 1
If Depth <= 0 Then Exit Function
Call DichotomySort(Arr(), low, DichotomySort, Operator, Depth)
Call DichotomySort(Arr(), DichotomySort + 1, high, Operator, Depth)
Exit Function
Err1:
Debug.Print LoopJs & " ERR:" & Err.Description
End Function
|
|