前言
数组是编程语言(VBA或者其他高级语言)中的不可多得的神器,其便捷性和高效性得到开发者的青睐。在VBA中数组也得到广泛的应用,但是VBA中数组的功能有时也令人觉得缺点儿什么,比如数组排序,在VBA中的数组就没有提供一个内置方法直接实现排序,在接下来的几篇文章中将陆续分享几种常用的实现方法。
经典算法 – 冒泡法
吹泡泡是每个人童年都必不可少的游戏,沾上肥皂水,轻轻一吹,大大小小的泡泡满天飞。
这种经典算法被称为冒泡法,就是指排序过程调整数组元素顺序就像水中的气泡会或快或慢地上浮到水面。
Sub BubbleSort()
Dim aintData(1 To 10) As Variant
Dim i As Integer
Dim j As Integer
Dim intLB As Integer
Dim intUB As Integer
Dim intTemp As Integer
intLB = LBound(aintData)
intUB = UBound(aintData)
For i = intLB To intUB
aintData(i) = Application.WorksheetFunction.RandBetween(1, 100)
Next i
Debug.Print "Original Data: " & Join(aintData, ",")
For i = intLB To intUB - 1
For j = intLB To intUB - i
If aintData(j) > aintData(j + 1) Then
intTemp = aintData(j)
aintData(j) = aintData(j + 1)
aintData(j + 1) = intTemp
End If
Next j
Next i
Debug.Print "After Sort: " & Join(aintData, ",")
End Sub
运行代码结果如下。
Original Data: 72,8,53,2,38,51,39,63,77,33
After Sort: 2,8,33,38,39,51,53,63,72,77
代码解析:
第10行到第12行代码使用For…Next循环结构,为数组aintData
赋值为1到100的随机数,其中Application.WorksheetFunction.RandBetween
引用工作表函数产出随机数。
第13行代码在立即窗口中输出数组的值,其中使用Join
方法,将数组的值组合为一个字符串。
第14行到第22行代码使用双重循环进行排序。
为了便于理解,先对下图中的标注进行说明。
- 编号为1~10的数据列分别代表数组
aintData
中10个元素的值 I-0
行为数组中的原始数据I-1
行为外层循环执行一次之后的数组值,I-2
、I-3
等等依次类推J-1-1
行为外层循环执行第一次时,内层循环执行一次之后的数组值,J-1-2
、J-4-1
等等依次类推
第一次运行第16行代码时j=1
,判断条件aintData(1) > aintData(2)
成立(即72>8
),接下来第17行到第19行代码将互换aintData(1)
和aintData(2)
的值,如下图中箭头所示,此时数组值如J-1-1
行。
第21行代码运行之后j=2
,内层循环将继续执行第16行代码,开始第2次执行内层循环。与上面过程类似,经过判断需要将aintData(2)
和aintData(3)
的值进行互换,完成后数组值如J-1-2
行。
注意J-1-8
行相对于J-1-7
行并没有发生任何数据调整。
… …
内层循环运行9次之后,将运行第22行代码,第一次外层循环运行结束,此时数组值如I-1
行。数组中的最大值77
被调整到aintData(10)
,类似于气泡冒出水面。
由于最后一个元素已经就位,第二次运行外层循环时,只需要处理第1至第9个数组元素。其过程与上面类似,此处不再赘述。
外层循环运行9次之后,完成全部数组排序,此时数组值如I-9
行。
此示例代码实现的是升序排序,如需使用降序,那么只需要修改第16行代码如下。
If aintData(j) < aintData(j + 1) Then
相关文章链接:
数组排序系列(1)-- 冒泡法
数组排序系列(2)-- 极值法
数组排序系列(3)-- 工作表排序法
数组排序系列(4)-- JavaScript排序法(数字升序)
数组排序系列(5)-- JavaScript排序法(数字降序)
数组排序系列(6)-- JavaScript排序法(字符排序)