学习Excel技术,关注微信公众号:
excelperfect
栈是一种常见的基础数据结构,用来实现后进先出的目的。比如,在桌子上摞了一堆书,最后放的书一定在最上面,最先拿走的也是最上面的书。
栈中的元素只能从栈顶进入,称为入栈,如下图1所示。栈中的元素只能从栈顶删除,称为出栈,如下图2所示。
图1
图2
在一些高级编程语言,例如C中,利用指针可以很容易实现栈结构。其实,在VBA中也很容易实现栈。
如下图3所示,变量siTop指向栈顶,从栈顶开始,每个元素项都指向其下一元素项,直至栈底。
图3
这里,使用了两个类模块:StackItem类模块、Stack类模块。
StackItem类模块
在StackItem类模块中,仅包含两个变量,变量Value用来包含每的元素的值,变量NextItem用来指向其下一元素项。StackItem类模块中的代码为:
'元素值
Public Value As Variant
'下一元素
Public NextItem As StackItem
注意到,在StackItem类模块中,变量NextItem声明为该类自身,正是因为这种自引用声明使VBA中可以生成动态的数据结构。
Stack类模块
在Stack类模块中,声明了一个指向栈顶的变量siTop,实现了入栈操作的Push方法、出栈操作的Pop方法、以及两个只读属性StackTop和StackEmpty,其中StackTop属性用来返回栈顶元素的值,StackEmpty属性返回栈是否为空,True表示栈中没有元素项,False表示栈中有元素项。
Stack类模块的代码:
代码语言:javascript复制'栈顶
Dim siTop As StackItem
'在栈顶添加新元素
Public Sub Push(ByVal varTextAs Variant)
Dim siNewTop As New StackItem
siNewTop.Value = varText
Set siNewTop.NextItem = siTop
Set siTop = siNewTop
End Sub
Public Function Pop() AsVariant
If Not StackEmpty Then
'从栈顶获取元素值
Pop = siTop.Value
'接着,设置新栈顶
Set siTop = siTop.NextItem
EndIf
End Function
'栈是否为空
Property Get StackEmpty() AsBoolean
StackEmpty = (siTop Is Nothing)
End Property
'栈顶元素值
Property Get StackTop() AsVariant
If StackEmpty Then
StackTop = Null
Else
StackTop = siTop.Value
End If
End Property
测试栈
下面的代码用来测试已实现的栈数据结果。在VBE中插入一个标准模块,在其中输入下面的代码:
代码语言:javascript复制Dim stkTest As New Stack
Sub TestStacks()
'入栈
stkTest.Push "Excel"
stkTest.Push "excelperfect"
stkTest.Push "完美Excel"
'出栈并打印元素值
Do While Not stkTest.StackEmpty
Debug.Print stkTest.Pop()
Loop
Debug.Print "--------------"
'入栈
stkTest.Push "测试"
Debug.Print stkTest.StackTop
End Sub
运行代码的结果如下图4所示。
图4