VBA中没有指针,但依旧可以模拟出链表,而且和C语言中的链表功能完全相同,使用方法也类似。可以实现节点的插入、删除。
以下是VBA的代码。不过代码正确性没有经过测试,只是一个可行的构想。
'定义双向链表的节点
Public Type Node
lastPtrNode As Long '上一个节点的指针。实际上是数组memory的索引
objectNmae As String '此处写入节点存放的数据
nextPtrNode As Long '下一个节点的指针。实际上是数组memory的索引
End Type
'在内存中保存节点的方式。实际上是数组memory中每个元素的类型
Public Type memoryNode
used As Boolean '该内存位置是否使用。实际上是数组memory的该元素,是否使用(默认False)
thisNode As Node '节点
End Type
'开辟一片内存,存放节点。实际上是定义一个数组,来储存所有节点
Public memory(100) As memoryNode
'获取指针指向的节点的数据。实际上是获取数组memory中指定元素的中的节点
Public Function GetNode(ByVal ptrNode As Long) As Node
GetNode = memory(ptrNode).thisNode
End Function
'创建一个新节点,并返回其指针。实际上是返回数组memory中的一个“未使用”的元素的节点,并将该元素设为“使用中”
Public Function NewNode() As Long
Dim i As Long
Dim j As Long
j = UBound(memory)
For i = 0 To j Step 1
If memory(i).used = False Then
memory(i).used = True
memory(i).thisNode.lastPtrNode = -1 '初始化链表。用-1代表指针的值为null
memory(i).thisNode.nextPtrNode = -1 '初始化链表。用-1代表指针的值为null
NewNode = memory(i).thisNode
Exit Function
End If
Next i
ReDim Preserve memory(j + 100) '扩大数组的存储空间
memory(j + 1).used = True
memory(i).thisNode.lastPtrNode = -1 '初始化链表。用-1代表指针的值为null
memory(i).thisNode.nextPtrNode = -1 '初始化链表。用-1代表指针的值为null
NewNode = memory(j + 1).thisNode
End Function
'释放节点的存储空间。实际上是将数组memory的指定元素设为“未使用”
Public Sub FreePtr(ByVal ptrNode As Long)
memory(ptrNode).used = False
End Sub
'删除ptrNode指向的节点,并释放存储空间
Public Sub DelectNode(ByVal ptrNode As Long)
Dim lastPtrNode As Long
Dim nextPtrNode As Long
lastPtrNode = memory(ptrNode).thisNode.lastPtrNode
nextPtrNode = memory(ptrNode).thisNode.nextPtrNode
If lastPtrNode <> -1 Then
memory(lastPtrNode).thisNode.nextPtrNode = nextPtrNode
End If
If nextPtrNode <> -1 Then
memory(nextPtrNode).thisNode.lastPtrNode = lastPtrNode
End If
memory(ptrNode).used = False
End Sub
'更新ptrNode指向的节点的数据
Public Sub UpdateNode(ByVal ptrNode As Long, ByVal updataNode As Node)
memory(ptrNode).thisNode = updataNode
End Sub
'创建新节点,并插入到ptrNode指向的节点的后面
Public Sub InsertNodeToNext(ByVal ptrNode As Long, ByVal insertNode As Node)
Dim thisPtrNode As Long
thisPtrNode = NewNode()
memory(thisPtrNode).thisNode = insertNode
Dim nextPtrNode As Long
nextPtrNode = memory(ptrNode).thisNode.nextPtrNode
If nextPtrNode = -1 Then '后面无节点
memory(ptrNode).thisNode.nextPtrNode = thisPtrNode
memory(thisPtrNode).thisNode.lastPtrNod = ptrNode
memory(thisPtrNode).thisNode.nextPtrNod = -1
Else
memory(thisPtrNode).thisNode.lastPtrNod = ptrNode
memory(thisPtrNode).thisNode.nextPtrNod = memory(ptrNode).thisNode.nextPtrNode
memory(ptrNode).thisNode.nextPtrNode = thisPtrNode
memory(memory(ptrNode).thisNode.nextPtrNode).thisNode.lastPtrNode = thisPtrNode
End If
End Sub
'创建新节点,并插入到ptrNode指向的节点的前面
Public Sub InsertNodeToNext(ByVal ptrNode As Long, ByVal insertNode As Node)
Dim thisPtrNode As Long
thisPtrNode = NewNode()
memory(thisPtrNode).thisNode = insertNode
If memory(ptrNode).thisNode.lastPtrNode = -1 Then '前面无节点
memory(ptrNode).thisNode.lastPtrNode = thisPtrNode
memory(thisPtrNode).thisNode.lastPtrNod = -1
memory(thisPtrNode).thisNode.nextPtrNod = ptrNode
Else
memory(thisPtrNode).thisNode.lastPtrNod = memory(ptrNode).thisNode.lastPtrNode
memory(thisPtrNode).thisNode.nextPtrNod = ptrNode
memory(ptrNode).thisNode.lastPtrNod = thisPtrNode
memory(memory(ptrNode).thisNode.lastPtrNod).thisNode.nextPtrNod = thisPtrNode
End If
End Sub