Linked List Containers
Linked Lists
List consists of multiple listnodes
Each listnode consists of
Data
Pointer to another node
Traditional view of data:
Data
Data
Data
Linked Lists
FAT
MAT
RAT
HAT
Insertion at a specific point:
Get a new node (allocate from memory)
Set data pointer
Set link of new node to previous node link
Set link of previous node link to new node
Linked Lists
FAT
FAT
MAT
RAT
RAT
Deletion at a specific point:
Set the link of the previous node to the link of the
node to delete.
Linked List Representations
Can locate data in any place in memory, not
required to be sequential
No requirements on computing size of list
beforehand
No more space than need
No bounds on space
No resizing
Still fairly trivial to manage and understand
Linked Lists in C++
Need to define a ListNode Class that represents:
Data
Pointer to another ListNode
Need to define a LinkedList Class that provides
container operations (Add, Delete, etc), using
ListNodes to implement the storage for the
container
Linked Lists in C++
Node definition:
class nodeName
{
private:
type dataName;
nodeName *link;
}
class ThreeLetterListNode
{
private:
char data[3];
ThreeLetterListNode * link;
}
Linked Lists in C++
Requirements for LinkedList construct:
Want to preserve encapsulation of nodes and ensure
that updating the data and link pointers are only
accomplished by the ListNode itself or the
LinkedList
Arbitrary and unlimited amount of memory
Characterize the LinkedList as: A LinkedList
consists of zero or more objects of type
ListNode.
Linked Lists
Linked List definition suggests that the List object
actually physically contains lots of ListNodes.
Contains a pointer, called first, to one ListNode, from
which the rest of the ListNodes can be found by
following links.
All ListNode objects are not physically contained within
the LinkedList object
To access private data members of ListNode class,
without making the data members public or having
public functions to set data and links,
make the LinkedList class a friend of the ListNode class:
Linked Lists
class LinkedList;
// forward declaration
template <class Type>
class ListNode {
friend class LinkedList<Type>;
private:
Type data;
ListNode *link;
};
ListNode.h
template<class Type>
class LinkedList {
public: // manipulation operations
private:
ListNode<Type> *first;
}
LinkedList.h
Forward Declarations
Forward Declarations:
Used when defining classes that rely on each other.
Indicates to compiler that the class in the forward
declaration is going to be defined later and is a valid
class.
Similar to use of function signatures to ensure
compiler sees all available functions.
Linked Lists
Linked List Node Constructor
Set
Data Value, Set Pointer
ListNode<Type>::ListNode<Type>(Type
inputData, ListNode<Type>* inputLink)
{
data = inputData;
link = inputLink;
}
List Operations
What operations do we want or need for the
LinkedList?
Constructor
Destructor
isEmpty()
isFull()
// doesn’t make sense in this context
add() (element?, position?)
delete() (element?, position?)
Linked Lists
Linked List Constructor
Creates an empty list
Essence of list is “first” pointer, so that should
be set to zero if empty
LinkedList<Type>::LinkedList<Type>()
{
first = 0;
}
Linked List Insertion
Function Interface:
void add(Type & toAdd);
Passed in a variable of type Type
1st step: Generate a new ListNode
Should hold value toAdd of type Type
Should point to nothing
Linked List Insertion
Node Creation: Node<Type> *node = new
Node<Type>(toAdd, 0);
Then need to insert in “right” place in list. What is right
place?
Depends on problem of interest
Sorted list? First in, first out list?
Let’s look at four cases:
Empty list
Non-empty, Front of list
Non-empty, Back of list
Non-empty, Arbitrary position in middle of list
Insertion into Empty List
Empty List
First
First
0
value
void LinkedList:<Type>:Add(Type & toAdd)
{
ListNode<Type> *node = new ListNode<Type>(toAdd, 0);
if (first == 0) first = node;
}
0
Insertion
Non-empty list, insert at front
first
value1
node
value3
value2
0
value1
first
0
value3
value2
0
Linked List Insertions
Insert at front method:
ListNode<Type> *node = new
ListNode<Type>(toAdd, first);
first = node;
Insertion
Non-empty list, insert at back
first
value1
node
value3
first
value2
0
0
value1
value2
value3
0
Linked List Insertions
Insert at back method:
// get to last node
ListNode<Type>* current = first;
while (current-> link != 0)
{
current = current->link;
}
// add
ListNode<Type>* node = new
current->link = node;
ListNode<Type>(toAdd, 0);
Insertion
Non-empty list, insert in middle
first
current
value1
node
value3
first
value2
0
0
value1
value3
value2
0
Linked List Insertions
Insert at arbitrary place:
ListNode<Type>* current = first;
while (someExpression holds)
// current->value < 5
{
// for example
current = current-> link;
}
ListNode<Type>* node =
new ListNode<Type>(value, current->link);
current->link = node;
Linked List Insertions
Insertion at front, insertion at end usually encapsulated
into two linked list methods:
Insert (at front), Append (onto back)
Insertion in middle could be encapsulated as
insertAtNth()
Usually seen instead as part of more complicated methods
(insertSorted for example)
Linked List: Deletion
How about deleting nodes?
Very similar to addition – 3 cases
Case 1: Delete from front
first
value1
value2
0
value3
first
value3
value2
0
Linked Lists: Deletion
Deletion from front:
ListNode<Type>* node = first;
first = first->link;
delete node;
Linked Lists: Deletion
Case 2: Delete from back
current
first
value1
previous
value2
0
value3
first
value1
value3
0
Linked Lists: Deletion
Deletion from back:
// get to just before last node
ListNode<Type>* previous =0;
ListNode<Type>* current = first;
while (current-> link != 0)
{
previous = current;
current = current->link;
}
previous->link = 0;
delete current;
Linked Lists: Deletion
Case 3: Delete from arbitrary location
previous
first
value1
value2
current
first
value1
0
value3
value2
0
Linked Lists: Deletions
ListNode<Type>* previous =0;
ListNode<Type>* current = first;
while (someExpression holds) //current->value !=
{
// value3 for example
previous = current;
current = current->link;
}
previous->link = current->link;
delete current;
Concatenate Example
Concatenate(LinkedList<Type> listB): Add all of the
elements of a second list to the end of the first list
Three cases:
ListA is empty – Set head for listA to head of listB
ListB is empty – No change, nothing to do
Both have data – Set pointer on last node of listA to head for
listB
This version of concatenate is:
Easy to implement
Destructive towards listsA and listB – as it potentially
changes how listA and listB work from here on out (listA
delete will now cause listB nodes to go away as well)
Concatenate Example
void LinkedList<Type>::concatenate(const
LinkedList<Type> & listB)
{
// empty list A
if (!first) { first = listB.first; return; }
}
else if (listB.first) // if b is empty do nothing
{
// get to end of my list (listA)
ListNode<Type>* current = first;
while (current->link != 0) { current = current->link; }
current->link = listB.first;
}
Safer Concatenate Example
LinkedList& LinkedList<Type>::concatenate(const
LinkedList<Type> & listB)
{
// make a copy of list A using copy constructor
LinkedList returnList = *(new LinkedList(*this));
}
if (listB.first) // if b is empty do nothing, else add to end
{
ListNode<Type>* current =listB.first;
while (current->link != 0)
{
This version returns a
listA.add(current->value);
new LinkedList which is a
current = current->link;
copy of listA with copies
of listB nodes added to
}
the end. Changes to the
return returnList; }
new list don’t affect listA
or listB.
© Copyright 2026 Paperzz