|
楼主 |
发表于 2015-12-4 15:13
|
显示全部楼层
本帖最后由 香川群子 于 2015-12-7 19:51 编辑
Function szpx(ar, h&, ParamArray sr())
'by kagawa 2015/12/4-12/7 主要参考借鉴了Zamyi大侠的二维数组多key排序算法
'第1参数ar:为待排序二维数组、第2参数h:为不参与排序的标题行的行数
'第3参数sr:为按权重优先顺序key、Sort值交替排列的一维数组、或以逗号分隔直接写入Key、Sort值。
该过程中增加了对空白单元格放到最后的处理代码
最后增加了稳定排序的处理。(最后的key值内容相同部分、还需按原始顺序升序排序)
- Function szpx(ar, h&, ParamArray sr()) 'by kagawa 2015/12/4-12/7 主要参考借鉴了Zamyi大侠的二维数组多key排序算法
- '第1参数ar:为待排序二维数组、第2参数h:为不参与排序的标题行的行数
- '第3参数sr:为按权重优先顺序key、Sort值交替排列的一维数组、或以逗号分隔直接写入Key、Sort值。
-
- Dim br, y, sr2, i&, i2&, i3&, i4&, j&, j2&, k&, l&, u&, s&, t
-
- l = LBound(ar) + h: u = UBound(ar) '获取数组起始、结束位置
- ReDim x&(l To u), z(l To u + 1) As Boolean '定义存放Index序号的数组x、标记段落结束位置的数组z
- For i = l To u
- x(i) = i 'Index赋值为数组行序号、这以后排序就只需改变这个Index位置、原始数组无需改变
- Next
- z(u + 1) = True '标记最后结束位置
-
- If UBound(sr) = 0 Then sr2 = sr(0) Else sr2 = sr '判断第3参数是数组、还是多Key、Sort值序列
- j = sr2(0): If sr2(1) Mod 2 Then Call QuickSort1(ar, x, j, l, u) Else Call QuickSort2(ar, x, j, l, u)
- '按key1先进行QuickSort排序
- If sr2(1) = 1 Then Call AZE(ar, x, j, l, u) '如果Sort值=1则需要调用AZE过程、把空值移动到最后
-
- For k = 2 To UBound(sr2) Step 2 '接着循环继续key2以后的排序
- ' br = szbr(ar, x, h): [k1].Resize(UBound(br) - LBound(br) + 1, UBound(br, 2) - LBound(br, 2) + 1) = br
- j2 = sr2(k): s = sr2(k + 1) '读取排序key的列序号j2 和Sort值s
- i = l: t = ar(x(i), j): i2 = i 'Do循环检查是否前key相同【注意,仅仅前key相同部分需要继续排序】
- Do
- Do
- i2 = i2 + 1: If z(i2) Then Exit Do Else If ar(x(i2), j) <> t Then z(i2) = True: Exit Do
- '递增检查如果到了前前key的结束位置、或前key不同则停止退出Do循环
- Loop
- If i2 - i > 1 Then '如果间隔>1 则本key需要排序处理【注意排序区间是小范围i,i2-1】
- If s Mod 2 Then Call QuickSort1(ar, x, j2, i, i2 - 1) Else Call QuickSort2(ar, x, j2, i, i2 - 1)
- If s = 1 Then Call AZE(ar, x, j2, i, i2 - 1) '如果Sort值=1则需要调用AZE过程、把空值移动到最后
- End If
- If i2 > u Then Exit Do Else i = i2: t = ar(x(i), j) '循环到最后时退出、否则继续从i2重新开始Do循环
- Loop
- j = j2 '更新前key列位置j
- Next
-
- '全部排序循环结束后、为保证最后的排序稳定性、检查最后的key值相同时必须按Index值排序。
- i = l: t = ar(x(i), j): i2 = i
- Do
- Do
- i2 = i2 + 1: If z(i2) Then Exit Do Else If ar(x(i2), j) <> t Then Exit Do '检查方法相同
- Loop
- If i2 - i > 1 Then Call QuickSort(x, i, i2 - 1) '如果间隔>1 则Index值需要排序处理
- If i2 > u Then Exit Do Else i = i2: t = ar(x(i), j) '循环到最后时退出、否则继续
- Loop
- szpx = x '多key稳定排序处理结束、返回排序结果的Index数组x
- ' szpx = szbr(ar, x, h) '或返回按排序后Index顺序引用返回的排序结果数组br
- End Function
复制代码 |
评分
-
1
查看全部评分
-
|