The standard template library supplies the programmer with a doubly linked list in the form of template class std::list.
STL's list class allows for constant time insertions at the front, back, or middle of the sequence.
Basic list Operations
Before use it, you need to include the header file <list>.
Instantiating a std::list Object
#include <list>
int main ()
{
using namespace std;
list <int> listIntegers;
return 0;
}
// This program produces no output
Inserting Elements at the Front of the list
#include <list>
#include <iostream>
int main ()
{
std::list <int> listIntegers;
listIntegers.push_front (10);
listIntegers.push_front (2001);
listIntegers.push_front (-1);
listIntegers.push_front (9999);
std::list <int> ::iterator iElementLocator;
for ( iElementLocator = listIntegers.begin ()
; iElementLocator != listIntegers.end ()
; ++ iElementLocator )
std::cout << *iElementLocator << std::endl;
return 0;
}
Output:
9999
-1
2001
10
Inserting Elements at the Back of the list
#include <list>
#include <iostream>
int main ()
{
std::list <int> listIntegers;
listIntegers.push_back (10);
listIntegers.push_back (2001);
listIntegers.push_back (-1);
listIntegers.push_back (9999);
std::list <int> ::iterator iElementLocator;
for ( iElementLocator = listIntegers.begin ()
; iElementLocator != listIntegers.end ()
; ++ iElementLocator )
std::cout << *iElementLocator << std::endl;
return 0;
}
Output:
10
2001
-1
9999
Inserting at the Middle of the list
std::list is characterized by its capability to insert elements at the middle of the collection in constant time. This is done using the member function insert.The list::insert member function is available in three forms:
- iterator insert(iterator pos, const T & x) This function returns an iterator to the recently inserted element in the list.
- void insert(iterator pos, size_type n, const T & x) n is the number of elements.
- template<class InputIterator> void insert(iterator pos, InputIterator f, InputIterator l)
#include <list>
#include <iostream>
using namespace std;
void PrintListContents (const list <int>& listInput);
int main ()
{
list <int> listIntegers1;
// Inserting elements at the beginning...
listIntegers1.insert (listIntegers1.begin (), 4);
listIntegers1.insert (listIntegers1.begin (), 3);
listIntegers1.insert (listIntegers1.begin (), 2);
listIntegers1.insert (listIntegers1.begin (), 1);
// Inserting an element at the end...
listIntegers1.insert (listIntegers1.end (), 5);
cout << "The contents of list 1 after inserting elements:" << endl;
PrintListContents (listIntegers1);
list <int> listIntegers2;
// Inserting 4 elements of the same value 0...
listIntegers2.insert (listIntegers2.begin (), 4, 0);
cout << "The contents of list 2 after inserting '";
cout << listIntegers2.size () << "' elements of a value:" << endl;
PrintListContents (listIntegers2);
list <int> listIntegers3;
// Inserting elements from another list at the beginning...
listIntegers3.insert (listIntegers3.begin (),
listIntegers1.begin (), listIntegers1.end ());
cout << "The contents of list 3 after inserting the contents of ";
cout << "list 1 at the beginning:" << endl;
PrintListContents (listIntegers3);
// Inserting elements from another list at the end...
listIntegers3.insert (listIntegers3.end (),
listIntegers2.begin (), listIntegers2.end ());
cout << "The contents of list 3 after inserting ";
cout << "the contents of list 2 at the beginning:" << endl;
PrintListContents (listIntegers3);
return 0;
}
void PrintListContents (const list <int>& listInput)
{
// Write values to the screen...
cout << "{ ";
std::list <int>::const_iterator iElementLocator;
for ( iElementLocator = listInput.begin ()
; iElementLocator != listInput.end ()
; ++ iElementLocator )
cout << *iElementLocator << " ";
cout << "}" << endl << endl;
}
Output:
The contents of list 1 after inserting elements:
{ 1 2 3 4 5 }
The contents of list 2 after inserting ‘4’ elements of a value:
{ 0 0 0 0 }
The contents of list 3 after inserting the contents of list 1 at the beginning:
{ 1 2 3 4 5 }
The contents of list 3 after inserting the contents of list 2 at the beginning:
{ 1 2 3 4 5 0 0 0 0 }
Erasing Elements in a list
The list member function erase comes in two overloaded forms: One that erases one element given an iterator that points to it and another that accepts a range and therefore erases a range of elements from the list.
#include <list>
#include <iostream>
using namespace std;
void PrintListContents (const list <int>& listInput);
int main ()
{
std::list <int> listIntegers;
// Insert elements at the beginning...
listIntegers.push_front (4);
listIntegers.push_front (3);
// Store an iterator obtained in using the 'insert' function
list <int>::iterator iElementValueTwo;
iElementValueTwo = listIntegers.insert (listIntegers.begin (), 2);
listIntegers.push_front (1);
listIntegers.push_front (0);
// Insert an element at the end...
listIntegers.push_back (5);
cout << "Initial contents of the list:" << endl;
PrintListContents (listIntegers);
listIntegers.erase (listIntegers.begin (), iElementValueTwo);
cout << "Contents after erasing a range of elements:" << endl;
PrintListContents (listIntegers);
cout<<"Contents after erasing element '"<<*iElementValueTwo<<"':"<<endl;
listIntegers.erase (iElementValueTwo);
PrintListContents (listIntegers);
listIntegers.erase (listIntegers.begin (), listIntegers.end ());
cout << "Contents after erasing a range:" << endl;
PrintListContents (listIntegers);
return 0;
}
void PrintListContents (const list <int>& listInput)
{
if (listInput.size () > 0)
{
// Write values to the screen...
cout << "{ ";
std::list <int>::const_iterator iElementLocator;
for ( iElementLocator = listInput.begin ()
; iElementLocator != listInput.end ()
; ++ iElementLocator )
cout << *iElementLocator << " ";
cout << "}" << endl << endl;
}
else
cout << "List is empty!" << endl;
}
Output:
Initial contents of the list:
{ 0 1 2 3 4 5 }
Contents after erasing a range of elements:
{ 2 3 4 5 }
Contents after erasing element ‘2’:
{ 3 4 5 }
Contents after erasing a range:
List is empty!
Reversing and Sorting Elements in a list
Reversing Elements
#include <list>
#include <iostream>
using namespace std;
void PrintListContents (const list <int>& listInput);
int main ()
{
std::list <int> listIntegers;
// Insert elements at the beginning...
listIntegers.push_front (4);
listIntegers.push_front (3);
listIntegers.push_front (2);
listIntegers.push_front (1);
listIntegers.push_front (0);
// Insert an element at the end...
listIntegers.push_back (5);
cout << "Initial contents of the list:" << endl;
PrintListContents (listIntegers);
listIntegers.reverse ();
cout << "Contents of the list after using reverse ():" << endl;
PrintListContents (listIntegers);
return 0;
}
void PrintListContents (const list <int>& listInput)
{
if (listInput.size () > 0)
{
// Write values to the screen...
cout << "{ ";
std::list <int>::const_iterator iElementLocator;
for ( iElementLocator = listInput.begin ()
; iElementLocator != listInput.end ()
; ++ iElementLocator )
cout << *iElementLocator << " ";
cout << "}" << endl << endl;
}
else
cout << "List is empty!" << endl;
}
Output:
Initial contents of the list:
{ 0 1 2 3 4 5 }
Contents of the list after using reverse ():
{ 5 4 3 2 1 0 }
Sorting Elements
#include <list>
#include <iostream>
using namespace std;
void PrintListContents (const list <int>& listInput);
bool SortPredicate_Descending (const int& lsh, const int& rsh);
int main ()
{
std::list <int> listIntegers;
// Insert elements at the beginning...
listIntegers.push_front (444);
listIntegers.push_front (300);
listIntegers.push_front (21111);
listIntegers.push_front (-1);
listIntegers.push_front (0);
// Insert an element at the end...
listIntegers.push_back (-5);
cout << "Initial contents of the list are - " << endl;
PrintListContents (listIntegers);
listIntegers.sort ();
cout << "Order of elements after sort():" << endl;
PrintListContents (listIntegers);
listIntegers.sort (SortPredicate_Descending);
cout << "Order of elements after sort() with a predicate:" << endl;
PrintListContents (listIntegers);
return 0;
}
void PrintListContents (const list <int>& listInput)
{
if (listInput.size () > 0)
{
// Write the output...
cout << "{ ";
std::list <int>::const_iterator iElementLocator;
for ( iElementLocator = listInput.begin ()
; iElementLocator != listInput.end ()
; ++ iElementLocator )
cout << *iElementLocator << " ";
cout << "}" << endl << endl;
}
else
cout << "List is empty!" << endl;
}
bool SortPredicate_Descending (const int& lsh, const int& rsh)
{
return (rsh < lsh);
}
Output:
Initial contents of the list are -
{ 0 -1 21111 300 444 -5 }
Order of elements after sort():
{ -5 -1 0 300 444 21111 }
Order of elements after sort() with a predicate:
{ 21111 444 300 0 -1 -5 }
Here is a example of a contacts list using std::list below:
// LISTING 19.8 - A List of Class Objects: Creating a Contacts List
#include <list>
#include <string>
#include <iostream>
using namespace std;
enum MenuOptionSelection
{
InsertContactListEntry = 0,
SortOnName = 1,
SortOnNumber = 2,
DisplayEntries = 3,
EraseEntry = 4,
QuitContactList = 5
};
struct ContactListItem
{
string strContactsName;
string strPhoneNumber;
// Constructor and destructor
ContactListItem (const string& strName, const string & strNumber)
{
strContactsName = strName;
strPhoneNumber = strNumber;
}
bool operator == (const ContactListItem& itemToCompare) const
{
return (itemToCompare.strContactsName == this->strContactsName);
}
bool operator < (const ContactListItem& itemToCompare) const
{
return (this->strContactsName < itemToCompare.strContactsName);
}
};
int ShowMenu ();
ContactListItem GetContactInfo ();
void DisplayContactList (const list <ContactListItem>& listContacts);
void EraseEntryFromList (list <ContactListItem>& listContacts);
bool Predicate_CheckItemsOnNumber (const ContactListItem& item1,
const ContactListItem& item2);
int main ()
{
list <ContactListItem> listContacts;
int nUserSelection = 0;
while ((nUserSelection = ShowMenu ()) != (int) QuitContactList)
{
switch (nUserSelection)
{
case InsertContactListEntry:
listContacts.push_back (GetContactInfo ());
cout << "Contacts list updated!" << endl << endl;
break;
case SortOnName:
listContacts.sort ();
DisplayContactList (listContacts);
break;
case SortOnNumber:
listContacts.sort (Predicate_CheckItemsOnNumber);
DisplayContactList (listContacts);
break;
case DisplayEntries:
DisplayContactList (listContacts);
break;
case EraseEntry:
EraseEntryFromList (listContacts);
DisplayContactList (listContacts);
break;
case QuitContactList:
cout << "Ending application, bye!" << endl;
break;
default:
cout << "Invalid input '" << nUserSelection << ".'";
cout << "Choose an option between 0 and 4" << endl << endl;
break;
}
}
cout << "Quitting! Bye!" << endl;
return 0;
}
int ShowMenu ()
{
cout << "*** What would you like to do next? ***" << endl << endl;
cout << "Enter 0 to feed a name and phone number" << endl;
cout << "Enter 1 to sort the list by name" << endl;
cout << "Enter 2 to sort the list by number" << endl;
cout << "Enter 3 to Display all entries" << endl;
cout << "Enter 4 to erase an entry" << endl;
cout << "Enter 5 to quit this application" << endl << endl;
cout << "> ";
int nOptionSelected = 0;
// Accept user input
cin >> nOptionSelected ;
cout << endl;
return nOptionSelected;
}
bool Predicate_CheckItemsOnNumber (const ContactListItem& item1,
const ContactListItem& item2)
{
return (item1.strPhoneNumber < item2.strPhoneNumber);
}
ContactListItem GetContactInfo ()
{
cout << "*** Feed contact information ***" << endl;
string strName;
cout << "Please enter the person's name" << endl;;
cout << "> ";
cin >> strName;
string strPhoneNumber;
cout << "Please enter "<< strName << "'s phone number" << endl;
cout << "> ";
cin >> strPhoneNumber;
return ContactListItem (strName, strPhoneNumber);
}
void DisplayContactList (const list <ContactListItem>& listContacts)
{
cout << "*** Displaying contact information ***" << endl;
cout << "There are " << listContacts.size ();
cout << " entries in the contact-list" << endl;
list <ContactListItem>::const_iterator iContact;
for ( iContact = listContacts.begin ()
; iContact != listContacts.end ()
; ++ iContact )
{
cout << "Name: '" << iContact->strContactsName;
cout << "' Number: '" << iContact->strPhoneNumber << "'" << endl;
}
cout << endl;
}
void EraseEntryFromList (list <ContactListItem>& listContacts)
{
cout << "*** Erase an entry ***" << endl;
cout << "Enter the name of the contact you wish to delete" << endl;
cout << "> ";
string strNameToErase;
cin >> strNameToErase;
listContacts.remove (ContactListItem (strNameToErase, ""));
}