1 Standard Containers: Lists Gordon College Resource: .
-
date post
20-Dec-2015 -
Category
Documents
-
view
215 -
download
0
Transcript of 1 Standard Containers: Lists Gordon College Resource: .
2
Lists
Another sequential container - the elements have a specific position within the container
Internal representation - next lecture
Problems with Vector (dynamic arrays):1. Insert/Deletion from middle of container - not efficient2. Insert/Deletion from end of container - not efficient if
this means expanding or deflating the size of the array(typically not viewed as much of a problem)
Solution - the List
3
Lists
Advantages to list containers:
* Efficient insertion and removal of elements anywhere in the container (constant time).
* Efficient moving elements and block of elements within the container or even between different containers (constant time).
* Iterating over the elements in forward or reverse order (linear time). * Like Vector - can expand and deflate as needed
perform generally better in inserting, extracting and moving elements in any position within the container
4
Lists
Disadvantage to list containers:
* lack direct access to elements by position (vector has direct access)
Must linearly search for a matching element.
5
The list Container
• A type-independent pattern for an array class– capacity can expand– self contained
• Declaration
template <typename T>
class list
{ . . . } ;
6
The list Container
Constructors list<int> first; // default - empty list of
ints
list<int> second (4,100); // four ints with value 100
list<int> third (second.begin(),second.end()); // iterating through second
list<int> fourth (third); // a copy of third
// the iterator constructor can also be used to construct from arrays:
int myints[] = {16,2,77,29}; list<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );
7
The list Container
Destructor ~list ( );
• The object's destructor gets called automatically when the object leaves scope.
8
A quick word about types
for(vector<string>::size_type i=0;i<strV.size();i++)cout << strV[i] << " ";
cout << endl;
Typically, we use int or unsigned types to deal with the index into a vector - however the “correct” way is to use a constant size_type associated with the class. Why? This makes our code work for all machine possibilities.
Same case for all other containers.
9
list Operations
• Information about a vector's contents– size_type size() const; L.size();– bool empty ( ) const;– size_type max_size () const;
• Basic access and add– reference back ( );– reference front ( );– void push_back ( const T& x );– void push_front ( const T& x );
10
list Operations
• Remove- iterator erase ( iterator position );
- iterator erase ( iterator first, iterator last );
it1 = mylist.erase (it1);
it1 = mylist.erase (it1,it2); Return: iterator pointing to the new location of the element that followed the last element erased
-void clear ( );
All the elements are dropped: destructors are called - leaving container with size of 0.
Remove by position
11
list Operations
• Remove- void pop_back ( );
- void pop_front ( );
Removes the elements from back (front) and reduces the size by 1.
Remove by position
- void resize ( size_type sz, T c = T() );
mylist.resize(5); mylist.resize(8,100); mylist.resize(12);
If the sz is smaller than listthen some of the elements are dropped (destructor called)
Default constructorfor type called
100 is used as fill
12
list Operations
• Remove- void remove ( const T& value );
Removes from the list all the elements with a specific value. This calls the destructor of these objects and reduces the list size by the amount of elements removed.
Remove by value
- void unique ( );
Removes all duplicate values - leaving only the first value
13
list Operations
• Add- iterator insert ( iterator position, const T& x );
- void insert ( iterator position, size_type n, const T& x );
- void insert ( iterator position, InputIterator first, InputIterator last );
mylist.insert (it,10); mylist.insert (it,2,20);
vector<int> myvector (2,30);mylist.insert (it,myvector.begin(),myvector.end());
14
list Operations
void swap ( list<T,Allocator>& lst );
list<int> first (3,100); list<int> second (5,200);
first.swap(second);
void reverse ( ); for (int i=1; i<10; i++) mylist.push_back(i);
mylist.reverse();OUTPUT?
15
list Operations
void splice ( iterator position, list<T,Allocator>& x );
// entire x is placed into list
void splice ( iterator position, list<T,Allocator>& x, iterator i );
// only element pointed to by iterator is placed into list
void splice ( iterator position, list<T,Allocator>& x, iterator first, iterator last );
// a range of elements from x is placed into list
16
sort list<string> mylist; list<string>::iterator it; mylist.push_back ("one"); mylist.push_back ("two"); mylist.push_back ("Three"); mylist.sort(); cout << "mylist contains:"; for (it=mylist.begin(); it!=mylist.end(); ++it) cout << " " << *it; cout << endl; mylist.sort(compare_nocase); cout << "mylist contains:"; for (it=mylist.begin(); it!=mylist.end(); ++it) cout << " " << *it; cout << endl;
17
sort list<string> mylist; list<string>::iterator it; mylist.push_back ("one"); mylist.push_back ("two"); mylist.push_back ("Three"); mylist.sort(); cout << "mylist contains:"; for (it=mylist.begin(); it!=mylist.end(); ++it) cout << " " << *it; cout << endl; mylist.sort(compare_nocase); cout << "mylist contains:"; for (it=mylist.begin(); it!=mylist.end(); ++it) cout << " " << *it; cout << endl;
bool compare_nocase (string first, string second){ unsigned int i=0; while ( (i<first.length()) && (i<second.length()) ) { if (tolower(first[i])<tolower(second[i]))
return true; else if (tolower(first[i])>tolower(second[i]))
return false; ++i; } if (first.length()<second.length()) return true; else return false;}
18
sort list<string> mylist; list<string>::iterator it; mylist.push_back ("one"); mylist.push_back ("two"); mylist.push_back ("Three"); mylist.sort(); cout << "mylist contains:"; for (it=mylist.begin(); it!=mylist.end(); ++it) cout << " " << *it; cout << endl; mylist.sort(compare_nocase); cout << "mylist contains:"; for (it=mylist.begin(); it!=mylist.end(); ++it) cout << " " << *it; cout << endl;
19
Predicateremove_if
A Predicate is a Unary Function whose result represents the truth or falsehood of some condition.
// a predicate implemented as a function:bool single_digit (const int& value) { return (value<10); }
// a predicate implemented as a class:class is_odd{public: bool operator() (const int& value) {return (value%2)==1; }};
EXAMPLE
mylist.remove_if (single_digit); mylist.remove_if (is_odd());
20
Predicateunique
bool same_integral_part (double first, double second){
return ( int(first)==int(second) ); }
EXAMPLE
mylist.unique (same_integral_part);
21
Contrast Lists and Vectors
Lists Vectors
• Constant time O(1) to add or remove elements from inside the list• Element access is linear• Constant time to move elements or blocks of elements within or between lists
• Linear time O(n) to add or remove elements from inside the list• Element access is constant• Linear time to move elements or blocks of elements within or between lists