代码改变世界

STL list

2011-08-11 17:03  Daniel Zheng  阅读(371)  评论(0编辑  收藏  举报

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

View Code
#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

View Code
#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

View Code
#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:

  1. iterator insert(iterator pos, const T & x)  This function returns an iterator to the recently inserted element in the list.
  2. void insert(iterator pos, size_type n, const T & x)  n is the number of elements.
  3. template<class InputIterator>  void insert(iterator pos, InputIterator f, InputIterator l)  
View Code
#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.

View Code
#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

View Code
#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

View Code
#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:

View Code
// 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,
""));
}