Chapter 17 Linked Lists: Starting Out With C++, 3 Edition
Chapter 17 Linked Lists: Starting Out With C++, 3 Edition
Chapter 17 Linked Lists: Starting Out With C++, 3 Edition
Declarations
First you must declare a data structure that
will be used for the nodes. For example, the
following struct could be used to create
a list where each node holds a float:
struct ListNode
{
float value;
struct ListNode *next;
};
Starting Out with C++, 3rd Edition
Declarations
The next step is to declare a pointer to serve
as the list head, as shown below.
ListNode *head;
17.2
We will use the following class declaration (on the next slide),
which is stored in FloatList.h.
class FloatList
{
private:
// Declare a structure for the list
struct ListNode
{
float value;
struct ListNode *next;
};
ListNode *head;
// List head pointer
public:
FloatList(void)
// Constructor
{ head = NULL; }
~FloatList(void); // Destructor
void appendNode(float);
void insertNode(float);
void deleteNode(float);
void displayList(void);
};
Program 17-1
// This program demonstrates a simple append
// operation on a linked list.
#include <iostream.h>
#include "FloatList.h
void main(void)
{
FloatList List;
list.appendNode(2.5);
list.appendNode(7.9);
list.appendNode(12.6);
}
(This program displays no output.)
Since head no longer points to NULL, the else part of the if statement executes:
else
{
The while loop's conditional test will fail after the first iteration
because nodePtr->next now points to NULL. The last
statement, nodePtr->next = newNode; causes
nodePtr->next to point to the new node. This inserts newNode
at the end of the list
The figure above depicts the final state of the linked list.
Starting Out with C++, 3rd Edition
void FloatList::displayList(void)
{
ListNode *nodePtr;
nodePtr = head;
while (nodePtr)
{
cout << nodePtr->value << endl;
nodePtr = nodePtr->next;
}
}
Program 17-2
// This program calls the displayList member function.
// The funcion traverses the linked list displaying
// the value stored in each node.
#include <iostream.h>
#include "FloatList.h"
void main(void)
{
FloatList List;
list.appendNode(2.5);
list.appendNode(7.9);
list.appendNode(12.6);
list.displayList();
}
Inserting a Node
Using the listNode structure again, the
pseudocode on the next slide shows an
algorithm for finding a new nodes proper
position in the list and inserting there.
The algorithm assumes the nodes in the list
are already in order.
The code for the traversal algorithm is shown below. (As before, num
holds the value being inserted into the list.)
// Initialize nodePtr to head of list
nodePtr = head;
// Skip all nodes whose value member is less
// than num.
while (nodePtr != NULL && nodePtr->value < num)
{
previousNode = nodePtr;
nodePtr = nodePtr->next;
}
Program 17-3
// This program calls the displayList member function.
// The function traverses the linked list displaying
// the value stored in each node.
#include <iostream.h>
#include "FloatList.h
void main(void)
{
FloatList list;
// Build the list
list.appendNode(2.5);
list.appendNode(7.9);
list.appendNode(12.6);
// Insert a node in the middle
// of the list.
list.insertNode(10.5);
// Dispay the list
list.displayList();
}
Starting Out with C++, 3rd Edition
Once again, the loop performs its test. Since nodePtr is not NULL
and nodePtr->value is less than num, the loop will iterate a
second time. During the second iteration, both previousNode and
nodePtr are advanced by one node in the list.
This time, the loop's test will fail because nodePtr is not less than
num. The statements after the loop will execute, which cause
previousNode->next to point to newNode, and
newNode->next to point to nodePtr.
If you follow the links, from the head pointer to the NULL, you will
see that the nodes are stored in the order of their value members.
Deleting a Node
Deleting a node from a linked list requires
two steps:
Remove the node from the list without breaking
the links created by the next pointers
Deleting the node from memory
Program 17-4
// This program demonstrates the deleteNode member function
#include <iostream.h>
#include "FloatList.h
void main(void)
{
FloatList list;
// Build the list
list.appendNode(2.5);
list.appendNode(7.9);
list.appendNode(12.6);
cout << "Here are the initial values:\n";
list.displayList();
cout << endl;
cout << "Now deleting the node in the middle.\n";
cout << "Here are the nodes left.\n";
list.deleteNode(7.9);
list.displayList();
cout << endl;
Program Output
Here are the initial values:
2.5
7.9
12.6
Now deleting the node in the middle.
Here are the nodes left.
2.5
12.6
Now deleting the last node.
Here are the nodes left.
2.5
Now deleting the only remaining node.
Here are the nodes left.
Look at the else part of the second if statement. This is where the
function will perform its action since the list is not empty, and the
first node does not contain the value 7.9. Just like insertNode,
this function uses nodePtr and previousNode to traverse the
list. The while loop terminates when the value 7.9 is located. At this
point, the list and the other pointers will be in the state depicted in
the figure below.
The last statement uses the delete operator to complete the total
deletion of the node.
Starting Out with C++, 3rd Edition
FloatList::~FloatList(void)
{
ListNode *nodePtr, *nextNode;
nodePtr = head;
while (nodePtr != NULL)
{
nextNode = nodePtr->next;
delete nodePtr;
nodePtr = nextNode;
}
}
17.3
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
template <class T>
class LinkedList
{
private:
// Declare a structure for the list
struct ListNode
{
T value;
struct ListNode *next;
};
Continued
ListNode *head;
on next slide
public:
LinkedList(void)
// Constructor
{ head = NULL; }
~LinkedList(void); // Destructor
void appendNode(T);
void insertNode(T);
void deleteNode(T);
void displayList(void);
};
// appendNode appends a node containing the
// value pased into num, to the end of the list.
template <class T>
void LinkedList<T>::AppendNode(T num)
{
ListNode *newNode, *nodePtr;
// Allocate a new node & store num
newNode = new ListNode;
Continued
newNode->value = num;
newNode->next = NULL;
on next slide
else
{
}
}
on next slide
else
{
// Initialize nodePtr to head of list
nodePtr = head;
// Skip all nodes whose value member is
// not equal to num.
while (nodePtr != NULL && nodePtr->value != num)
{
previousNode = nodePtr;
nodePtr = nodePtr->next;
}
// Link the previous node to the node after
// nodePtr, then delete nodePtr.
previousNode->next = nodePtr->next;
delete nodePtr;
}
}
// Destructor
// This function deletes every node in the list.
template <class T>
LinkedList<T>::~LinkedList(void)
{
ListNode *nodePtr, *nextNode;
nodePtr = head;
while (nodePtr != NULL)
{
nextNode = nodePtr->next;
delete nodePtr;
nodePtr = nextNode;
}
}
#endif
Program 17-5
// This program demonstrates the linked list template.
#include <iostream.h>
#include "LinkedList.h
void main(void)
{
LinkedList<int> list;
// Build the list
list.appendNode(2);
list.appendNode(4);
list.appendNode(6);
cout << "Here are the initial values:\n";
list.displayList();
cout << endl;
Program Output
Here are the initial values:
2
4
6
Now inserting the value 5.
Here are the nodes now.
2
4
5
6
Now deleting the last node.
Here are the nodes left.
2
4
5
Member Function
back
erase
list.erase(iter);
list.erase(firstIter, lastIter)
The first example causes the list element pointed to by the iterator
iter to be removed. The second example causes all of the list
elements from firstIter to lastIter to be removed.
empty
if (list.empty())
The empty member function returns true if the list is empty. If
the list has elements, it returns false.
Member Function
end
iter = list.end();
end returns a bi-directional iterator to the end of the list.
front
insert
list.insert(iter, x)
The insert member function inserts an element into the list. The
example shown above inserts an element with the value x, just before
the element pointed to by iter.
merge
list1.merge(list2);
merge inserts all the items in list2 into list1. list1 is
expanded to accommodate the new elements plus any elements
already stored in list1. merge expects both lists to be sorted.
When list2 is inserted into list1, the elements are inserted into
their correct position, so the resulting list is also sorted.
Member Function
pop_back
list.pop_back();
pop_back removes the last element of the list.
pop_front
list.pop_front();
pop_front removes the first element of the list.
push_back
list.push_back(x);
push_back inserts an element with value x at the end of
the list.
push_front
list.push_front(x);
push_front inserts an element with value x at the beginning of the
list.
reverse
list.reverse();
reverse reverses the order in which the elements appear in the list.
Member Function
size()
swap
list1.swap(List2)
The swap member function swaps the elements stored in two
lists. For example, assuming list1 and list2 are lists, the
statement shown above will exchange the values in the two.
unique
list.unique();
unique removes any element that has the same value as the element
before it.
Program 17-6
// This program demonstrates the STL list container.
#include <iostream.h>
#include <list>
// Include the list header
using namespace std; // Required by some compilers
void main(void)
{
list<int> myList;
list<int>::iterator iter;
// Add values to the list
for (int x = 0; x < 100; x += 10)
myList.push_back(x);
// Display the values
for (iter = myList.begin(); iter != myList.end(); iter++)
cout << *iter << " ";
cout << endl;