User:Eriksiers/Linked List: Difference between revisions

From Rosetta Code
Content added Content deleted
(created)
 
(fixed a few bugs^H^H^H^H brain farts)
Line 4: Line 4:
Private Type Node
Private Type Node
data As Variant
data As Variant
prev As Variant
nPrv As Variant
next As Variant
nNxt As Variant
End Type
End Type


Line 58: Line 58:
listEmpty = False
listEmpty = False
curNode = 0
curNode = 0
nodes(0).prev = 0
nodes(0).nPrv = 0
nodes(0).next = 0
nodes(0).nNxt = 0
Else
Else
Dim tmp As Variant
Dim tmp As Variant
tmp = UBound(nodes) + 1
tmp = UBound(nodes) + 1
ReDim Preserve nodes(tmp)
ReDim Preserve nodes(tmp)
'this If splices the new node into the list
'this If block splices the new node into the list
If Before = where Then
If Before = where Then
nodes(nodes(curNode).next).prev = tmp
nodes(nodes(curNode).nNxt).nPrv = tmp
nodes(tmp).next = nodes(curNode).next
nodes(tmp).nNxt = nodes(curNode).nNxt
nodes(tmp).prev = curNode
nodes(tmp).nPrv = curNode
nodes(curNode).next = tmp
nodes(curNode).nNxt = tmp
Else
Else
nodes(nodes(curNode).prev).next = tmp
nodes(nodes(curNode).nPrv).nNxt = tmp
nodes(tmp).next = curNode
nodes(tmp).nNxt = curNode
nodes(tmp).prev = nodes(curNode).prev
nodes(tmp).nPrv = nodes(curNode).nPrv
nodes(curNode).prev = tmp
nodes(curNode).nPrv = tmp
End If
End If
curNode = tmp
curNode = tmp
Line 89: Line 89:
If UBound(nodes) > 0 Then
If UBound(nodes) > 0 Then
'patch the surrounding elements together
'patch the surrounding elements together
nodes(nodes(curNode).prev).next = nodes(curNode).next
nodes(nodes(curNode).nPrv).nNxt = nodes(curNode).nNxt
nodes(nodes(curNode).next).prev = nodes(curNode).prev
nodes(nodes(curNode).nNxt).nPrv = nodes(curNode).nPrv
'select the appropriate next item
'select the appropriate nNxt item
curNode = nodes(curNode).next
curNode = nodes(curNode).nNxt
'finally, the actual delete
'finally, the actual delete
ReDim Preserve nodes(UBound(nodes) - 1)
ReDim Preserve nodes(UBound(nodes) - 1)
Line 103: Line 103:
Else
Else
'patch the surrounding elements together
'patch the surrounding elements together
nodes(nodes(curNode).prev).next = nodes(curNode).next
nodes(nodes(curNode).nPrv).nNxt = nodes(curNode).nNxt
nodes(nodes(curNode).next).prev = nodes(curNode).prev
nodes(nodes(curNode).nNxt).nPrv = nodes(curNode).nPrv
'swap with node at end of list
'swap with node at end of list
Dim tmp As Node
Dim tmp As Node
Line 111: Line 111:
nodes(curNode) = tmp
nodes(curNode) = tmp
'patch the list
'patch the list
nodes(nodes(curNode).prev).next = curNode
nodes(nodes(curNode).nPrv).nNxt = curNode
nodes(nodes(curNode).next).prev = curNode
nodes(nodes(curNode).nNxt).nPrv = curNode
'select the appropriate next item
'select the appropriate nNxt item
If UBound(nodes) <> nodes(UBound(nodes)).next Then curNode = nodes(UBound(nodes)).next
If UBound(nodes) <> nodes(UBound(nodes)).nNxt Then curNode = nodes(UBound(nodes)).nNxt
'finally, the actual delete
'finally, the actual delete
ReDim Preserve nodes(UBound(nodes) - 1)
ReDim Preserve nodes(UBound(nodes) - 1)
Line 123: Line 123:


Public Function nextnode() As Boolean
Public Function nextnode() As Boolean
If curNode < UBound(nodes) Then
curNode = nodes(curNode).nNxt
curNode = curNode + 1
Else
curNode = 0
End If
nextnode = True
End Function
End Function


Public Function prevNode() As Boolean
Public Function prevNode() As Boolean
If curNode > 0 Then
curNode = nodes(curNode).nPrv
curNode = curNode - 1
Else
curNode = UBound(nodes)
End If
prevNode = True
End Function</lang>
End Function</lang>



Revision as of 12:44, 21 August 2012

This is a linked list class for Visual Basic & VBA. It should work at least as far back as VB4.

<lang vb>'This class is in the Public Domain. Private Type Node

   data As Variant
   nPrv As Variant
   nNxt As Variant

End Type

Public Enum BeforeOrAfter

   Before = 0
   After = 1

End Enum

Private nodes() As Node Private curNode As Variant, listEmpty As Boolean

Private Sub Class_Initialize()

   listEmpty = True
   curNode = -1

End Sub

Public Property Get nodeData() As Variant

   If listEmpty Then
       Error 9
   Else
       nodeData = nodes(curNode).data
   End If

End Property

Public Property Let nodeData(ByVal vNewValue As Variant)

   If listEmpty Then
       Error 9
   Else
       nodes(curNode).data = vNewValue
   End If

End Property

Public Property Get isEmpty() As Boolean

   isEmpty = listEmpty

End Property

Public Property Get currentNode() As Variant

   currentNode = curNode

End Property

Public Property Get nodeCount() As Variant

   If listEmpty Then
       nodeCount = 0
   Else
       nodeCount = UBound(nodes) + 1
   End If

End Property

Public Function insertNode(Optional where As BeforeOrAfter, Optional data As Variant) As Boolean

   If listEmpty Then
       ReDim nodes(0)
       listEmpty = False
       curNode = 0
       nodes(0).nPrv = 0
       nodes(0).nNxt = 0
   Else
       Dim tmp As Variant
       tmp = UBound(nodes) + 1
       ReDim Preserve nodes(tmp)
       'this If block splices the new node into the list
       If Before = where Then
           nodes(nodes(curNode).nNxt).nPrv = tmp
           nodes(tmp).nNxt = nodes(curNode).nNxt
           nodes(tmp).nPrv = curNode
           nodes(curNode).nNxt = tmp
       Else
           nodes(nodes(curNode).nPrv).nNxt = tmp
           nodes(tmp).nNxt = curNode
           nodes(tmp).nPrv = nodes(curNode).nPrv
           nodes(curNode).nPrv = tmp
       End If
       curNode = tmp
   End If
   nodes(curNode).data = data
   insertNode = True

End Function

Public Function deleteNode() As Boolean

   If listEmpty Then
       Error 9
   Else
       If UBound(nodes) = curNode Then
           If UBound(nodes) > 0 Then
               'patch the surrounding elements together
               nodes(nodes(curNode).nPrv).nNxt = nodes(curNode).nNxt
               nodes(nodes(curNode).nNxt).nPrv = nodes(curNode).nPrv
               'select the appropriate nNxt item
               curNode = nodes(curNode).nNxt
               'finally, the actual delete
               ReDim Preserve nodes(UBound(nodes) - 1)
           Else
               'only item on list, so...
               ReDim nodes(0)
               listEmpty = True
               curNode = -1
           End If
       Else
           'patch the surrounding elements together
           nodes(nodes(curNode).nPrv).nNxt = nodes(curNode).nNxt
           nodes(nodes(curNode).nNxt).nPrv = nodes(curNode).nPrv
           'swap with node at end of list
           Dim tmp As Node
           tmp = nodes(UBound(nodes))
           nodes(UBound(nodes)) = nodes(curNode)
           nodes(curNode) = tmp
           'patch the list
           nodes(nodes(curNode).nPrv).nNxt = curNode
           nodes(nodes(curNode).nNxt).nPrv = curNode
           'select the appropriate nNxt item
           If UBound(nodes) <> nodes(UBound(nodes)).nNxt Then curNode = nodes(UBound(nodes)).nNxt
           'finally, the actual delete
           ReDim Preserve nodes(UBound(nodes) - 1)
       End If
       deleteNode = True
   End If

End Function

Public Function nextnode() As Boolean

   curNode = nodes(curNode).nNxt

End Function

Public Function prevNode() As Boolean

   curNode = nodes(curNode).nPrv

End Function</lang>

Simplified

This is a variation of the above class that relies on VB's array handling to keep the elements in order. It's much simpler than the above version, but will slow significantly with larger lists. (How large and how slow are largely dependent on the machine it's running on.)

With minor modifications, this could conceivably work under QBasic (though obviously not as a class).

<lang vb>'This class is in the Public Domain. Public Enum BeforeOrAfter

   Before = 0
   After = 1

End Enum

Private nodes() As Variant Private curNode As Variant, listEmpty As Boolean

Private Sub Class_Initialize()

   listEmpty = True
   curNode = -1

End Sub

Public Property Get nodeData() As Variant

   If listEmpty Then
       Error 9
   Else
       nodeData = nodes(curNode)
   End If

End Property

Public Property Let nodeData(ByVal vNewValue As Variant)

   If listEmpty Then
       Error 9
   Else
       nodes(curNode) = vNewValue
   End If

End Property

Public Property Get isEmpty() As Boolean

   isEmpty = listEmpty

End Property

Public Property Get currentNode() As Variant

   currentNode = curNode

End Property

Public Property Get nodeCount() As Variant

   If listEmpty Then
       nodeCount = 0
   Else
       nodeCount = UBound(nodes) + 1
   End If

End Property

Public Function insertNode(Optional where As BeforeOrAfter, Optional data As Variant) As Boolean

   If listEmpty Then
       ReDim nodes(0)
       listEmpty = False
       curNode = 0
   Else
       ReDim Preserve nodes(UBound(nodes) + 1)
       Dim L0 As Variant
       curNode = curNode + where
       For L0 = UBound(nodes) To curNode + 1 Step -1
           nodes(L0) = nodes(L0 - 1)
       Next
   End If
   nodes(curNode) = data
   insertNode = True

End Function

Public Function deleteNode() As Boolean

   If listEmpty Then
       Error 9
   Else
       Dim L0 As Variant
       For L0 = curNode To UBound(nodes) - 1
           nodes(L0) = nodes(L0 + 1)
       Next
       If UBound(nodes) < 1 Then
           listEmpty = True
           curNode = -1
       Else
           ReDim Preserve nodes(UBound(nodes) - 1)
       End If
       deleteNode = True
   End If

End Function

Public Function nextNode() As Boolean

   If curNode < UBound(nodes) Then
       curNode = curNode + 1
   Else
       curNode = 0
   End If
   nextNode = True

End Function

Public Function prevNode() As Boolean

   If curNode > 0 Then
       curNode = curNode - 1
   Else
       curNode = UBound(nodes)
   End If
   prevNode = True

End Function</lang>