210 likes | 338 Views
Standard Containers: Lists. Gordon College. Resource: http://www.cplusplus.com. Lists. Another sequential container - the elements have a specific position within the container Internal representation - next lecture Problems with Vector (dynamic arrays):
E N D
Standard Containers: Lists Gordon College Resource: http://www.cplusplus.com
Lists Another sequential container - the elements have a specific position within the container Internal representation - next lecture Problems with Vector (dynamic arrays): • Insert/Deletion from middle of container - not efficient • 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
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
Lists Disadvantage to list containers: * lack direct access to elements by position (vector has direct access) Must linearly search for a matching element.
The list Container • A type-independent pattern for an array class • capacity can expand • self contained • Declaration template <typename T> class list { . . . } ;
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) );
The list Container Destructor ~list ( ); • The object's destructor gets called automatically when the object leaves scope.
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.
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 );
list Operations • Remove - iterator erase ( iterator position ); - iterator erase ( iterator first, iterator last ); it1 = mylist.erase (it1); it1 = mylist.erase (it1,it2); Remove by position 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.
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() ); Default constructor for type called mylist.resize(5); mylist.resize(8,100); mylist.resize(12); If the sz is smaller than list then some of the elements are dropped (destructor called) 100 is used as fill
list Operations • Remove - void remove ( const T& value ); Remove by 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. • void unique ( ); • Removes all duplicate values - leaving only the first value
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());
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?
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
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;
sort 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; } 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;
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;
Predicateremove_if A Predicate is a Unary Function whose result represents the truth or falsehood of some condition. EXAMPLE // 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; } }; mylist.remove_if (single_digit); mylist.remove_if (is_odd());
Predicateunique EXAMPLE bool same_integral_part (double first, double second) { return ( int(first)==int(second) ); } mylist.unique (same_integral_part);