Now we have the building blocks to create a simple linked list. But managing nodes by hand is tedious and error-prone. So, much like we created an ArrayList to manage a dynamic array for us, we will create a LinkedList class to manage a linked list of nodes for us. The class will be responsible for creating, linking, and deleting the nodes as needed.
An absolutely minimal implementation of a SimpleLinkedList will just have one member variable: a pointer to keep track of the first node in the list. We typically call this node the head of the list. When the list is empty, the head pointer will be nullptr.
The SimpleLinkedList objects themselves will be variables we create on the stack using something like SimpleLinkedList<int> myList1;. Any nodes they are keeping track of will be allocated on the heap.
Figure27.3.1.Two simple linked lists. myList1 is empty and thus it has a nullptr head pointer. myList2 is managing a linked list that starts at the node containing the value 6. So myList2βs head pointer points to the node containing 6.
We could have a SimpleLinkedList object that was allocated on the heap, but that is less common. The whole point of the linked list is to manage dynamic memory for us so we donβt have to. Allocating the list object itself on the heap would just add unnecessary complexity.
We want to be able to store any type of value in our linked list, so we will make the SimpleLinkedList a class template. We will also need to change our ListNode to be a template so that it can store any type of value. First, here is how we could define a templated ListNode:
template<typename T>
struct Node {
T element;
Node* next = nullptr;
Node(T value) {
element = value;
}
};
An absolutely minimal implementation of a SimpleLinkedList will just have one member variable: a pointer to keep track of the first node in the list. We typically call this node the head of the list. We will also need a few behaviors to manage and test the list:
class SimpleLinkedList {
private:
ListNode<T>* head = nullptr; // Pointer to the first node in the list
public:
// Construct an empty linked list
SimpleLinkedList();
// Destructor to clean up the list
~SimpleLinkedList();
// Add a new element to the front of the list
void insertStart(T value);
// Print all elements in the list
void print() const;
};
The constructor is easy. Because the list starts out empty, we just set the head pointer to nullptr. That is already done in the member variable declaration, so the constructor body can be empty.