Linked Lists
| Introduction | Inserting Nodes |
| Pointers | Deleting Nodes |
| Creating Lists | Destroying Lists |
| Printing Lists | Warning |
One of the dynamic data structures than can be constructed is the linked list. A linked list can be pictured as a collection of elements or nodes, each containing some data as well as a link, or pointer, to the next node in the list.

Each node in the linked list must contain at least two fields. The first is the data field. It can be a simple integer, a character, a string or even a large structure or object containing many fields. This will be referred to here as the Info field. The second field is the pointer, or link, to the next node in the list. This will be referred to as the nextNode field.

Recall that an object reference, or pointer, contains the address in memory of an object. In most machines this is an integer value, since memory locations have integer addresses. However, an object reference cannot be assigned an integer value.
Pointers are important for creating dynamic data structures such as linked lists, since they provide a way of linking each component to the next component in the structure. Because the only types of pointers that Visual Basic provides are references to objects, a linked list in VB must use objects for its nodes.
The "node class" should include a nextNode variable that indicates the next node in the list. It should also include variables to hold whatever data the program needs to manipulate. These variables should be declared Private within the class. Sample code for the linkNode class follows:
|
|
Because each node is an object, the New statement must be used to create new nodes. It assigns their variable values and uses their nextNode references to connect them.
An external pointer to the list is also needed so that the program can access the entire list. Nodes in a linked list are not accessed directly or randomly. Instead, the first node is accessed through the external pointer, the second node through the first node's pointer, the third node through the second node's pointer, etc., to the end of the list. To indicate where the list ends, the nextNode element of the last node can be set to Nothing.

The following code sample demonstrates how to create a linked list of four nodes of type ListNode, all linked together. For the sake of the example, one of the data components of each node has been set to store the loop control variable.
|
|
![]()
Ptr2 = New linkNode
Ptr2.setInfo (lcv)
result in:
![]()
If lcv = 1 Then
Ptr1 = Ptr2
List = Ptr2
result in:
![]()
In the next iteration of the loop....
Ptr2 = New linktNode
Ptr2.setInfo (lcv)
result in:
![]()
Else
Ptr1.setNextNode(Ptr2)
results in:
![]()
Ptr1 = Ptr2 results in:
![]()
Eventually the code results in:
![]()
Notice that the value Nothing is assigned to the last pointer in the list. Nothing is indicated graphically by placing a slash (\) across the field whose value is Nothing. When traversing the list, the program can compare the link field of each component in the list to Nothing to see when the end of the list has been reached.
![]()
As linked lists become more familiar, they will be created by the insertion of nodes one at a time as they are needed by calling the appropriate insertion procedure.
Printing A
Linked
List
To print the elements in a linked list, the value of the first element is printed, then the second, then the third and so on until the end of the list is reached. This algorithm involves a simple loop to traverse the list, using a temporary pointer to point to each successive node. The temporary pointer, Ptr, is first initialized to the beginning of the list with the statement
Ptr = List
To print the value of the node pointed to by Ptr
Print Ptr.getInfo ( ) ' replace getInfo with the correct accessor method
and to move Ptr to the next node
Ptr = Ptr.getNextNode( )
This process is repeated until the end of the loop is reached. This is indicated when the pointer variable is Nothing.
While Not Ptr Is Nothing
The entire procedure to print all the values in the linked list might look like the following. Note that this sub, as well as all following subs, are included in a class called clsLinkedList that has a single instance variable, List, of type linkNode.
|
|
Inserting
Into A
Linked
List
A procedure for inserting a node into a linked list must have two parameters: a linked list and the element to be inserted. There are two ways of inserting -- either inserting an element as the first element in the list or inserting an element into its proper place depending on the order of the list elements.
![]()
Inserting
as
the
first
element ....
To insert an element as the first one in an existing linked list requires two steps: create the element and insert it at the beginning of the list. The program must first create the element set its pointer to the first element in the list, and then set the list pointer to point to the new element. (Note that before calling
pushNode the first time (i.e., if the List has no elements), List should be initialized to
Nothing.)
|
|
Dim newNode As New ListNode ' create new node
![]()
newNode.setInfo (nodeValue) ' set value of new node
![]()
newNode.setNextNode(List) ' make nextNode point to start of List
![]()
List = newNode ' reset List to newNode
| Click for animation |
![]()
Compare this to the code that would be needed to add a new item to the beginning of an array. In an array, every entry would have to be moved one space to make room for the new item. If the array is long, the insertion operation could take a long time. With a linked list, an insertion can be accomplished in just two steps.
The following algorithm is more versatile. Instead of merely inserting an item at the beginning of a list, it accepts a value and places it in its proper position, regardless of whether that position is at the beginning, middle, or end of a linked list.
![]()
Inserting
In
the
Proper
Position ....
To insert an element in the proper place in a sorted list requires that the proper position in the list be determined. This requires looping through all the nodes until a node with a greater
Info field is found.
Ptr = List
While Ptr.getInfo( ) < nodeValue
Ptr =
Ptr.nextNode
If the node referenced by
Ptr is the one whose value is greater than the one to be inserted, then the new element should be inserted before that node. In other words, the pointer has passed the position where the new element should be inserted.
Since the program needs to know the previous node in the list so that it can change its pointer field to point to the new
element, the insertion algorithm must maintain an additional pointer, Back, to keep track of the previous node.
Ptr = List
While Ptr.getInfo( ) < nodeValue
Back =
Ptr
Ptr =
Ptr.nextNode
Wend
This algorithm is sufficient for handling the insertion of elements at the front of the list or inside the list, but it requires modification before it can
handle elements that need to be added at the end of the list.
The algorithm contains the statement
While Ptr.getInfo( ) < nodeValue
If the element to be inserted is greater than any element in the list, which will require an insertion at the end of the list, the loop does not end before Ptr is set to Nothing. The loop then tries to access Ptr.nextNode when Ptr has been set to Nothing, which results in an error message. Therefore the loop needs to have two conditions -- it must be executed while Not Ptr Is Nothing and while Ptr.GetInfo is less than the element to be inserted. However, the code
While (Not Ptr Is Nothing) And (Ptr.getInfo( ) < nodeValue)
does not work, because VB evaluates both sides of the expression, even if the first evaluates to false. The situation remains the same -- even after Ptr is set to Nothing, the compiler attempts to evaluate Ptr.getInfo, resulting in an error condition.
A Boolean variable provides a solution. It will be initialized to False and changed to True when the insertion point is found.
While (Not Ptr Is Nothing) And Not Found
This takes care of all three cases: the insertion at the front, the middle, and the end. The following procedure represents a general insertion algorithm.
|
'------------------------------------------------------------------------------------------------------------------- |
Insertion at beginning:
Goal: Insert 3 into the list. First the procedure gets a new node, P, and puts 3 in the Info field. The Back pointer is set to Nothing, the loop pointer
Ptr is set to List, and Found is set to False.
![]()
Since Ptr is not Nothing and Found is False, the While loop is executed. Ptr.getInfo( ) is greater than nodeValue (5 > 3), so Found is set to True. The While loop is terminated. P.nextNode is set to Ptr. Back is Nothing (indicating that the new element will be the first), so List is set to P.
Insertion in the middle:
Goal: Insert 6 into the list. The initialization is the same as above
![]()
The expression in the If statement (Ptr.getInfo ( ) > nodeValue) is False (3 < 4), so Back is set to Ptr and Ptr is advanced to Ptr.nextNode. The While loop is executed again and now the expression in the If statement (5 > 4) is True, so Found is set to True.
![]()
The While loop is not executed since Found is now True. P.nextNode is set to Ptr.
![]()
Back is not Nothing so Back.nextNode is set to P.
![]()
The final results of the insertion appear below.
| Click for animation |
Goal: Insert 9 into the list. The initialization is the same as above.
![]()
The expression in the If statement (Ptr.getInfo ( ) > nodeValue) is False (5 < 9), so Back is set to Ptr and Ptr is advanced to Ptr.nextNode.
![]()
The While loop is executed again and still the expression in the If statement (Ptr.getInfo ( ) > nodeValue) is False (7 < 9), so Back is set to Ptr and Ptr is advanced to Ptr.nextNode, which is Nothing.
![]()
The While loop is not executed because the condition (Not Ptr Is Nothing) is False . P.nextNode is set to Ptr (Nothing in this case) and Back.nextNode is set to P.
![]()
The final results of the insertion appear below.
| Click for animation |
There are two types of
deletions: deleting the first node or deleting a node with a specified Info
field.
To delete the first node, the program sets the List pointer to the second node,
sets the first node's nextNode link to Nothing, and removes the reference to the
first node so that it will be disposed of. The code for this procedure follows:
|
|
Deleting the First Node in a List
P = List
![]()
List = List.getNextNode( )
![]()
P.setNextNode(Nothing)
![]()
P = Nothing
![]()
The resulting list, after garbage collection takes place, is shown below:
| Click here for animation |
The following algorithm is more versatile. Instead of merely deleting the node at the beginning of a list, it accepts a value and locates the node with that value, and deletes it regardless of whether it is located at the beginning, middle, or end of a linked list.
Deleting a Node with a
Specified Value
To delete a node whose Info field has a certain value requires that the list be searched until a node with the same value is found.
|
|
The process of removing the node containing 7 follows:
Ptr = List
Back = Nothing
![]()
While
(Not Ptr Is Nothing) And Not Found
If Ptr.getInfo( ) = targetNode Then
Found = True
Else
Back =
Ptr
![]()
While Ptr.getInfo( ) <> targetNode
:
Ptr = Ptr.getNextNode( )
![]()
If Back Is Nothing Then
List =
List.getNextNode( )
Else
Back.setNextNode(Ptr.getNextNode( ))
End If
![]()
Ptr.setNextNode(Nothing)
Ptr = Nothing
![]()
The resulting list, after garbage collection takes place, is shown below:
| Click here for animation |
To destroy a linked list, set the List pointer to Nothing.
When the List reference is set to Nothing, the reference count of the first node in the list is reduced to zero, so the garbage collector reclaims that node. As it destroys the first node, the system detects that the node contains a reference to another node in the nextNode variable. Because the first node is being destroyed, the reference count of the second node is also reduced. That makes the reference count for the second object in the list also zero, so the system reclaims it as well. This process continues in a chain reaction until every node in the list has been reclaimed by the system. As long as the program does not contain other references to objects in the list, the entire linked list can be destroyed with a single statement: List = Nothing

![]()

![]()

![]()

![]()

![]()
![]()
| Click here for animation |
Given:
The statement P = Q yields:
Now both P and Q refer to the same object that contains 9. The node containing 7 still exists, but P no longer refers to it. In fact, unless there is another reference to the node, then that node is lost forever. While it will remain in memory until it is reclaimed by the garbage collector, but there is no path to reach it.
|
|
|
'
clsLinkedList
Private List As New linkNode
'------------------------------------------------------------------------------------------------------------------- |
|
|