【VB】预留排序法

哈里在最近的编程生活中,突发奇想,开始着手文本的分析。

期间涉及到了数组的排序。于是想也没想祭出了自己祖传的“扑克牌排序法”,即插值排序。

不过当后期数组元素个数大于100万的时候,祖传方法明显慢了下来,需要长达几十分钟的排序(VB.6.0与VB.net均如此,VB6.0更慢)。

在排序算法的优化中,想到了一种新型排序方法:预留排序法。(新算法100万条数据仅需29毫秒,名字起的比较随意)

预留排序法的步骤主要有三步:

1、找到需要排序数组的最大值。

2、获取需要排序数组的每种出现过的值的重复数量。

3、通过内存位置预测,将需要排序的数组的遍历序放入排序索引数组完成排序。

VB6.0实例如下:(百万条数据3.6秒)

Public Function 预留法排序(数组() As Long, 排序() As Long)
    Dim 数量() As Long, i As Long, 数组最大值 As Long, 偏移() As Long
    ReDim 排序(UBound(数组))
    For i = 1 To UBound(数组)
        If 数组(i) > 数组最大值 Then
            数组最大值 = 数组(i)
        End If
    Next
    ReDim 数量(数组最大值), 偏移(数组最大值)
    For i = 1 To UBound(数组)
        数量(数组(i)) = 数量(数组(i)) + 1
    Next
    For i = 1 To UBound(数组)
        偏移(数组(i)) = 偏移(数组(i)) + 1
        排序(数组求和(数量, 数组(i)) + 偏移(数组(i))) = i
    Next
End Function
Private Function 数组求和(数组() As Long, 截止序 As Long) As Long
    Dim i As Long
    For i = LBound(数组) To 截止序 - 1
        数组求和 = 数组求和 + 数组(i)
    Next
End Function

不得不说VB.NET的运算速度比VB6.0快得多得多,所以VB.net的实例哈里也准备了一份:(百万条数据29毫秒)

Public Sub 预留法排序(数组() As Long, 排序() As Long)
    Dim 数量() As Long, i As Long, 数组最大值 As Long, 偏移() As Long
    ReDim 排序(UBound(数组))
    '获得数组最大值
    For i = 1 To UBound(数组)
        If 数组(i) > 数组最大值 Then
            数组最大值 = 数组(i)
        End If
    Next
    ReDim 数量(数组最大值), 偏移(数组最大值)
    '重复值划分统计
    For i = 1 To UBound(数组)
        数量(数组(i)) += 1
    Next
    '最终排序
    For i = 1 To UBound(数组)
        偏移(数组(i)) += 1
        排序(数组求和(数量, 数组(i)) + 偏移(数组(i))) = i
    Next
End Function
Private Function 数组求和(数组() As Long, 截止序 As Long) As Long
    Dim i As Long, 输出 As Long
    For i = LBound(数组) To 截止序 - 1
        输出 += 数组(i)
    Next
    Return 输出
End Function

(PS:以上所有耗时数据基于Intel i9 9900K默频。)

你可能感兴趣的:(VB遇到的那些事)