查看: 22  |  回复: 0
  VBA代码 二维数组排序
楼主
发表于 2025年3月18日 10:20
Option Explicit

Private Sub test()
    Dim arr, brr
    arr = Range("A2:C25")
    brr = ArrSort2(arr, 2)    'arr对第2列作为关键字培训
    brr = ArrSort2(brr, 3)    '对brr第3列作为关键字培训
    Range("E2").Resize(UBound(arr), UBound(arr, 2)) = brr
End Sub

'下面是二维数组排序

Function ArrSort2(arr, key&)    '二维数组排序
    '二维数组 过程封转 返回排序后数组
    'arr=待排序二维数组 key=排序的列
    Dim i&, j&
    ReDim indexarr(LBound(arr) To UBound(arr)) As Long
    For i = LBound(arr) To UBound(arr)    '构造序号数组
        indexarr(i) = i
    Next
    ReDim brr(LBound(arr) To UBound(arr), LBound(arr, 2) To UBound(arr, 2))
    QuickSort2 arr, indexarr, key, LBound(arr), UBound(arr)
    '***Start**根据原始index顺序调整快速排序引起的不稳定排列
    '找出连续相等的序号起止 调用一维数组排序对序号数组排序 恢复index顺序
    i = LBound(arr)    '重排起点
    Dim istart&, iend&    '需要重排的序号数组下标 就是连续相同的局部
    istart = LBound(arr)

    For i = istart + 1 To UBound(arr)    '连续行判断 详细算法详见 连续行单元格合并
        'If arr(indexarr(istart), key) = 10 Then Stop
        If arr(indexarr(istart), key) = arr(indexarr(i), key) Then    '相等则连续编号 1
            j = j + 1
        Else
            iend = istart + j
            If j > 0 Then    '不相等且有连续相等的元素 对本段序号数组重排
                QuickSort indexarr, istart, iend
            End If
            j = 0
            istart = i    '分段起点下移一位
        End If
    Next

    If j > 0 Then    '最后一个区间处理 如果在循环内检测边界比较浪费 所以放在最后
        QuickSort indexarr, istart, UBound(arr)
    End If

    '***End***根据原始index顺序调整快速排序引起的不稳定排列

    '***Start***根据排好的行号输出结果二维数组
    For i = LBound(arr) To UBound(arr)
        For j = LBound(arr, 2) To UBound(arr, 2)
            brr(i, j) = arr(indexarr(i), j)
        Next
    Next
    ArrSort2 = brr
End Function

Private Function QuickSort2(ar, x() As Long, j2&, l&, u&)
    '升序二维数组快速排序  按原数组j2列对应内容进行升序排序
    '传入参数ar=源数据 x=上下标一致的一维数组 j2为排序的列标
    Dim i&, j&, n, r
    i = l: j = u: r = ar(x((l + u) \ 2), j2)
    While i < j
        While ar(x(i), j2) < r And i < u: i = i + 1: Wend    'A-Z
        While ar(x(j), j2) > r And j > l: j = j - 1: Wend    'A-Z
        If i <= j Then n = x(i): x(i) = x(j): x(j) = n: i = i + 1: j = j - 1
    Wend
    If l < j Then Call QuickSort2(ar, x, j2, l, j)
    If i < u Then Call QuickSort2(ar, x, j2, i, u)
End Function
'''下面是一维数组排序 郑广学 整理 2019.12.18

Function ArrSort(arr)
    '一维数组排序 过程封转 返回排序后数组
    Dim brr
    brr = arr
    QuickSort brr, LBound(brr), UBound(brr)
    ArrSort = brr
End Function

Sub QuickSort(tr, l&, u&)
    'tr为原始一维数组 L为排序起始下标 U为上标
    'EH论坛香川群子改进快速排序算法
    Dim i&, j&, x, t
    x = tr(l): i = l + 1: j = u
    Do
        Do While i < u
            If tr(i) > x Then Exit Do Else i = i + 1
        Loop
        Do While j > l
            If tr(j) < x Then Exit Do Else j = j - 1
        Loop
        If i < j Then t = tr(i): tr(i) = tr(j): tr(j) = t Else Exit Do
    Loop
    
    If j > l Then t = tr(l): tr(l) = tr(j): tr(j) = t: Call QuickSort(tr, l, j)
    If j + 1 < u Then Call QuickSort(tr, j + 1, u)
End Sub


您需要登录后才可以回帖 登录 | 立即注册
【本版规则】请勿发表违反国家法律的内容,否则会被冻结账号和删贴。
用户名: 立即注册
密码:
2020-2025 MaNongKu.com