The Standard Template Library Container Classes Version 1.0.

Post on 06-Jan-2018

233 views 0 download

description

There are two general kinds of containers: Sequential Containers Associative Containers

transcript

The Standard Template Library

Container ClassesVersion 1.0

The Standard Template Library provides a setof template classes designed to help you organizedata in various useful ways.

These are called containers or sometimes theyare called collection classes.

There are two general kinds of containers:

Sequential ContainersAssociative Containers

Sequence Containers

Sequence containers are ordered collectionsEvery element has a certain position Position depends on time and place of insertionThere are three predefined sequence containers:

VectorDequeList

Associative Containers

Associative containers are sorted collectionsThe position of an element depends upon its value Position is independent of the order of insertionThere are four predefined associative containers:

SetMulti-setMapMulti-map

Common Container Abilities

All containers provide value rather than reference semantics. That is, containers copy elements internally when they are inserted, rather than managing references to them. Thus,each element in a container must have a public copyconstructor.

Common Container Abilities

All containers have an order. Each container provides functions that return an iterator that can be used tomove through the elements in the container in order.

Common Container Abilities

In general, operations on containers are not safe. It isthe programmer’s responsibility to make sure that allparameters of an operation are valid and meet the requirements of the operation. Violating these requirements will result in an undefined behavior.Usually the STL does not throw exceptions!

Common Operations All container classes provide the following:

Operation Effect

CType c creates an empty containerCType c1(c2) creates a container c1, copying c2 into it (c1 and c2 are the same type of container)

InitializationEvery container class comes with a default constructor, a copy constructor, and a destructor.

Constructors are provided to initialize acontainer with the elements of anothercontainer or from an array.

vector<int> v;create an empty vector

list<float> l;. . .vector<float> v(l.begin( ), l.end( ));

create a vector and initialize it from a list

int array[ ] = { 2, 17, 23, 46, 22};. . .vector<int> v(array, array+sizeof(array)/sizeof(array[0]) );

create a vector and initialize from an array

Common Operations All container classes provide the following:

Operation Effect

CType c creates an empty containerCType c1(c2) creates a container c1, copying c2 into itc.size( ) returns the number of elements in cc.empty( ) returns true if the container c is emptyc.max_size( ) returns the maximum number of elements ever possiblec1 == c2 returns true if the containers of the same type are equal c1 != c2 returns true if the containers are not equal

Comparison operations are defined based on the following three rules:

1. Both containers are of the same type2. Two containers are equal if their elements are equal and have the same order.3. Lexicographical comparison is done to see if one container is less (or greater) than another.

Common Operations All container classes provide the following:

Operation Effect

c1.swap(c2) swaps the data in c1 and c2 (c1 and c2 are of the same type)c.begin( ) returns an iterator for the first element in cc.end( ) returns a sentinel marking the last element in cc.rbegin( ) returns a reverse iterator for the last element in cc.rend( ) returns a sentinel marking the first element in cc.clear( ) erases all elements from c - makes the container emptyc.~CType<T>( ) destroys all elements and frees the memory

Efficiency of operations

Operation vector list dequeConstructor( ) O(1) O(1) O(1)Constructor(size) O(1) O(n)+ O(1)Constructor(size, value) O(n) O(n) O(n)at(int) O(1) --- O(1)push_back(value) O(1)+ O(1) O(1)+

begin( ) / end( ) O(1) O(1) O(1)operator[ ] O(1) --- O(1)

O(1) – independent of the number of elementsO(n) – linear, depends on the value of n

VectorsVectors store their elements in an internal dynamic array.

You can access any element of a vector in constant time provided you know where the element is.

Vectors provide good performance when adding or deleting elements at the end, but inserting or deleting in the middle is very expensive. This is because every element behind has to be moved to a new position. Insertion time is not constant!

Vectors grow as required, but “growing” a vector is expensive, and invalidates all references, pointers and iterators for elements of the vector

AssignmentsAssignment (e.g. c1 = c2) is very expensive for anycontainer class. Every element of the left containeris destroyed and a copy made of every element ofthe right container. The default constructor, copyconstructor, and overloaded assignment operatorsare used for each element in the copied container.

If you don’t need to re-use the source container,then the swap( ) function is much more efficientthan doing an assignment, as it only swaps pointers. Itdoes not make a copy.

Element AccessOperation Effect

c.at(idx) returns the element at index idx. Throws an exception if idx is out of range

c[idx] returns the element at idx, no range checking

c.front( ) returns the first element (no check to see if one exists)

c.back( ) returns the last element (no check to see if one exists)

Inserting and Deleting ElementsThere are a number of operations defined to insertand delete elements from a Vector.

Inserting and Deleting Elements

Operation Effect

c.insert(pos,elem) inserts a copy of elem at pos and returns the position of the new element (pos is an iterator).

c.push_back(elem) adds a copy of elem at the end of the vector

c.pop_back( ) removes the last element in the vector

c.erase(pos) removes the element at position pos and returns the position of the next element.

c.resize(num) changes the size of the vector to num. Calls the default constructor for new elements.

iterators must refer to valid positions. Do not try toremove an element from an empty container.

4 7 19 -5 vector<int> v

vector<int>::iterator p

vector<int>::iterator vp = v.insert(p, 27);

4 7 19 -5 vector<int> v

vp

vector<int>::iterator vp = v.insert(p, 27);

27

#include <iostream>#include <vector>#include <string>using namespace std;

int main ( ){

vector<string> sentence;sentence.reserve(10);sentence.push_back("Hello,");sentence.push_back("how");sentence.push_back("are");sentence.push_back("you?");

vector<string>::iterator p;for (p = sentence.begin( ); p != sentence.end( ); p++)

cout << *p << " ";cout << endl;

system("PAUSE");return 0;

}

DequesPronounced “deck”, a Deque is similar to a vector.

It manages its elements with a dynamic arrayIt provides random access

A deque allows insertions and deletions at both ends,Which is fast. Insertion into the middle is slow.Element access and iterator movement is a bit slowerthan with a vector.Deques do not support the functions capacity( )and reserve( )

Grows like a vector – but in both directions

Choose a deque if …You need to insert or delete from either end of the container

You do not need to randomly accessdata in the container

Inserting and Deleting Elements

Operation Effect

c.insert(pos,elem) inserts a copy of elem at pos and returns the position of the new element.

c.push_back(elem) adds a copy of elem at the end of the deque

c.pop_back( ) removes the last element in the deque

c.push_front(elem) adds a copy of elem at the front of the deque

c.pop_front( ) removes the first element in the deque

iterators must refer to valid positions. Do not try toremove an element from an empty container.

new

new

The assign function

void container::assign(size_type num, const T& value);

The assign function replaces all existing elements ofthe container with num occurences of value.

#include <iostream>#include <deque>#include <string>using namespace std;

int main ( ){

deque<string> sentence;sentence.assign(3, string("middle stuff") );sentence.push_back("end string");sentence.push_front("front_string");

deque<string>::iterator p;for (p = sentence.begin( ); p != sentence.end( ); p++)

cout << *p << "\n ";cout << endl;

system("PAUSE");return 0;

}

ListsLists are very different from vectors and deques

A list does not provide random access.accessing an arbitrary element is slow.

Inserting and deleting elements is fastat any position, not just the first and last.

Inserting and deleting elements does notinvalidate pointers, references, or iterators.

Lists have the best exception safety of all ofthe STL containers. Either an operation worksor it is a no-op in almost all cases.

Element AccessBecause a list does not support random access, onlythe following functions are provided for direct access:

c.front( )c.back( )

All other access must be done through iterators.Only bi-directional iterators are supported. Thus,you cannot call algorithms that require randomaccess iterators. Sorting algorithms fall in thiscategory.

Inserting and Deleting Elements

Operation Effect

c.insert(pos,elem) inserts a copy of elem at pos and returns the position of the new element.

c.push_back(elem) adds a copy of elem at the end of the deque

c.pop_back( ) removes the last element in the deque

c.push_front(elem) adds a copy of elem at the front of the deque

c.pop_front( ) removes the first element in the deque

r.remove(val) removes all elements with the value val

r.remove_if(op) removes all elements for which op(elem) is true

iterators must refer to valid positions. Do not try toremove an element from an empty container.

new

new

Splice FunctionsLinked lists have the advantage that you can insert and deleteelements at any point in the list in constant time. Lists supporta number of unique functions to change the order of and re-linkelements in a list.

Splice FunctionsLinked lists have the advantage that you can insert and deleteelements at any point in the list in constant time. Lists supporta number of unique functions to change the order of and re-linkelements in a list.

This is accomplished by manipulating pointers

Operation Effect

c.unique( ) removed duplicates of consecutive elements

c1.splice(pos, c2) moves all elements of c2 to c1 in front of the iterator position pos

c1.splice(pos, c2, c2p) moves the element at c2p to c1 in front of the iterator position pos

c1.splice(pos, c2, c2b, c2e) moves all elements in the range [c2b, c2e] in c2 to c1 in front of the iterator position pos

c.sort( ) sorts all elements of c using <

c.sort(op) sorts all elements of c using op( )

c1.merge(c2) assuming that c1 and c2 are sorted, moves all elements of c2 into c1 so that the resulting list is still sorted

#include <iostream>#include <list>#include <string>using namespace std;

int main ( ){

list<string> sentence;sentence.assign(3, string("middle stuff") );sentence.push_back("end string");sentence.push_front("front_string");

list<string>::iterator p;for (p = sentence.begin( ); p != sentence.end( ); p++)

cout << *p << "\n";cout << endl;

system("PAUSE");return 0;

}

cout << "\n\nSorted List\n\n";sentence.sort( );for (p = sentence.begin( ); p != sentence.end( ); p++)

cout << *p << "\n";cout << endl;

Sets and MultisetsSets and multisets sort their elements automaticallyaccording to a certain sorting criteria. Multisets allowduplicate elements, while sets do not.

The sorting criteria must define strict weak ordering:

It has to be antisymmetric for <, if x < y is true, then y < x is false

It has to be transitive for <, if x < y is true and y < z is true, then x < z is true

It has to be irreflexive for <, x < x is always false

13

4

69

11

4

49

Set

Multiset

52

4 9

7

11

8

Sets and multisets are usually storedinternally as balanced binary trees.

(You will learn about trees in data structures.)

Sets and multisets do not provide any operations fordirect element access.

You may not change the value of an element directlybecause this may affect the ordering. You have to remove the element that has the old value and insertthe element with the new value.

Constructors

Operation Effect

set<T> c A set that sorts with < operator

set<T, op> c A set that sorts with op

multiset<T> c A multiset that sorts with < operator

multiset<T, op> c A multiset that sorts with op

set<int, greater<int> > collection;

Special Search Operations

Operation Effect

count (elem) returns the number of elements with value elem

find (elem) returns the position of the first element with value elem

Inserting and Removing Elements

Operation Effect

c.insert(elem) inserts a copy of elem and returns the position (and for sets whether or not it succeeded)

c.insert(pos, elem) inserts a copy of elem, using pos as a hint of where

c.erase(elem) removes all elements of value elem

c.Erase (pos) removes the element at pos

c.clear( ) removes all elements from the set

Iterators

Iterators are bidirectional, and can’t be used in algorithmsthe require random access.

Most importantly, from the iterator’s point of view, allelements are considered constant. Thus you cannot usean iterator in any modifying algorithm on elements of aset or a multiset.

#include <iostream>#include <iterator>#include <set>#include <string>using namespace std;

int main ( ){

set<int> nums;nums.insert(17);nums.insert(3);nums.insert(12);nums.insert(6);nums.insert(3);

set<int>::iterator p;for (p = nums.begin( ); p != nums.end( ); p++)

cout << *p << "\n";

cout << endl;system("PAUSE");return 0;

}

note that the values are in order.and 3 only appears once.

Maps and MultimapsMaps and multimaps mange key/data pairs aselements and sort their contents automaticallyaccording to a certain sorting criteria that isused for the actual key.

2 x

1 y4 z

5 y

key value

Constructors

Operation Effect

map<Key, T> c A map that sorts keys with < operator

map<Key, T, op> c A map that sorts keys with op

multimap<Key, T> c A multimap that sorts keys with < operator

multimap<Key, T, op> c A multimap that sorts keys with op

Special Search Operations

Operation Effect

count (k) returns the number of elements with key k

find (k) returns the position of the first element with key k

IteratorsIterators are bidirectional, and can’t be used in algorithmsthat require random access.

Most importantly, from the iterator’s point of view, allelements are considered constant. Thus you cannot usean iterator in any modifying algorithm on elements of amap or a multimap.

Maps as Associative ArraysNon-constant maps provide a subscript operatorfor direct element access. However, the index ofthe subscript operator is not the integer positionof the element, but it is the key that is used toidentify the element.

#include <iostream>#include <map>#include <string>using namespace std;

int main ( ){

map<string, float> stocks;stocks["GM"] = 456.34;stocks["Ford"] = 321.87;stocks["BMW"] = 256.90;stocks["Audi"] = 123.78;

map<string, float>::iterator p;for (p = stocks.begin( ); p != stocks.end( ); p++)

cout << p->first << " " << p->second << "\n";cout << "\n\n" << stocks["Audi"];

cout << endl;system("PAUSE");return 0;

}

keydata

sorted by key

When to Use Which Container

characteristic vector deque list set map

internal store dynamic array array of arrays binary tree binary tree binary tree

elements value value value value key/value pair

random access yes yes no no no iterator category random access random access bidirectional bidirectional bidirectional

search/find elements slow slow very slow fast fast for key

insert/remove at the back at front & back anywhere -- --elements

insert/remove on reallocation always never never never invalidates pointers,references, & iterators

Container AdaptersContainer adapters modify the standard containers to fitspecial needs.

Stacks

Queues

Priority Queues

StackA stack is a first-in, last-out container. It providesthe following interface:

Operation Effect

push( ) inserts an element into the stack

pop( ) removes an element from the stack

top( ) returns the top element in the stack

push poptop

QueueA queue is a first-in, first-out container. It implements the following interface:

Operation Effect

push( ) inserts an element into the queue

front( ) returns the next element in the queue

pop( ) removes an element from the queue

back ( ) returns the last element

push

pop

back

front

Priority QueueA priority queue is a queue from whichelements are read in priority order.

Operation Effect

push( ) inserts an element into the queue

top( ) returns the highest priority element in the queue

pop( ) removes an element from the queue

push

pop

top

elements are prioritized according to their value

BitsetsBitsets are fixed sized arrays of bits, or boolean values.They are useful for managing sets of flags