Title: An Introduction to STL Standard Template Library
1An Introduction to STL - Standard Template
Library
- Jiang Hu
- Department of Electrical Engineering
- Texas AM University
2What Is STL?
- C based implementations of general purpose data
structures and algorithms
3When Do You Need STL?
- Reduce your C/C programming time
- Use data structures and algorithms from STL
directly, instead of implementing everything from
scratch - Easier maintenance
- Bugs in bottom structures are the most difficult
to find - Use STL as building blocks, they are robust
- Program runtime is not very critical
- General purpose implementations may run a little
slower than customized implementations
4Assumption
- You know basics of
- C
- Data structures such as link list, hash table,
binary search tree - Algorithms such as sorting
5Bottom Line Understand class
- class is
- An essential concept for C
- What STL is built on
- An abstract form
- Has member variables to record data
- Has member functions to do something
- Members can be open to public or encapsulated to
be private
6Example of class
- class node
- private
- long x, y, ID
- double rat, cap
- node parent
- public
- node(long id)
- void setCoordinates( long, long )
- long getID()
- nodenode(long id) x(0), y(0), ID(id),
parent(NULL) - long nodegetID()
- return ID
- main()
-
- node myNode(1)
- myNode.setCoordinates(5,8)
- long p myNode.getID()
7STL Containers
- Sequence containers
- vector
- deque
- list
- Sorted associative containers
- set
- multiset
- map
- multimap
8STL list
- list is a list
- Functionally, similar to double-linked list
- Supports
- Insertion
- Deletion
- Sorting
-
9Example of list
- include ltlist.hgt
- void doSomething()
-
- listltnodegt nodeList
-
- nodeList.push_back( node(1) ) // node1 is
added at end - nodeList.push_front( node(0) ) // node0 is
added at front - nodeList.pop_back() // remove the element
at end - nodeList.pop_front() // remove the element
at front -
10STL iterator
begin()
end()
list
- include ltlist.hgt
- void doSomething()
-
- listltnodegt nodeList
- listltnodegtiterator j // Generalized
pointer -
- for ( j nodeList.begin() j !
nodeList.end() j ) - if ( (j).getID() gt 3 ) break
-
-
11 insert(), erase() and remove()
- include ltlist.hgt
- void doSomething()
-
- listltnodegt nodeList
- listltnodegtiterator j // Generalized
pointer -
- for ( j nodeList.begin() j !
nodeList.end() j ) - if ( (j).getID() gt 3 ) nodeList.insert(
j, node(2) ) - if ( (j).getID() lt 0 ) nodeList.erase( j
) // problem?? -
- nodeList.remove( nodeA ) // operator
defined for node -
12 Careful erase in a loop
- include ltlist.hgt
- void doSomething()
-
- listltnodegt nodeList
- listltnodegtiterator j, k
-
- j nodeList.begin()
- while ( j ! nodeList.end() )
- k j
- if ( (k).getID() lt 0 )
- nodeList.erase( k )
-
-
-
13front() and back()
- include ltlist.hgt
- void doSomething()
-
- listltnodegt nodeList
-
- node A nodeList.front() // copy the
first node in the list - node B( nodeList.back() ) // construct a
node B same as - //
the last node in the list -
14size(), sort() and merge()
- include ltlist.hgt
- void doSomething()
-
- listltnodegt listA, listB
-
- int numNodes listA.size() // number of
elements in list - listA.sort() // operatorlt is defined
for node - listB.sort()
- listA.merge( listB ) // both lists should
be sorted - // listB becomes
empty after merge -
15STL vector
- Functionality-wise, roughly a subset of list
- No push_front(), pop_front(), remove(), sort(),
merge() - Supports operator , such as vectorA3
- Then why need vector ?
- Faster access if the data are mostly static or
not much insertion/deletion
16STL deque
- Very similar to vector, except
- Supports push_front() and pop_front()
- No operator
- Also friendly to accessing static data
17 vector vs. array in C/C
- Dynamic memory management for vector
- Certain size of memory is allocated when a vector
is constructed - When add a new element and the memory space is
insufficient, multiple-sized new memory is
allocated automatically
18Use reserve() if possible
- If you have a rough idea of the size of the
vector, use reserve() to allocate sufficient
memory space at the beginning - Dynamic memory allocation is nice, but it costs
you runtime, the related copying also takes time - Ex., you will work on a routing tree for a net
with k sinks, then - vectorltnodegt nodeVec
- const int a 2
- nodeVec.reserve( ak )
19Sequence Container Summary
- Contiguous-memory based
- vector, constant time addition and deletion at
end - deque, constant time addition and deletion at
beginning and end - Constant time access
- Linear time insertion/deletion in middle
- Node based list
- Linear time access
- Constant time insertion/deletion any position
20Sorted Associative Containers
- setltkeygt a set of sorted key which can be any
data type with operatorlt defined - multisetltkeygt allow duplicative keys
- mapltkey, Tgt T is a certain data type, the data
are always sorted according to their keys - multimapltkey, Tgt allow duplicative keys
- Internally, implemented via red-black tree
21STL map
- include ltmap.hgt
- void doSomething()
-
- mapltstring, double, lessltstringgt gt tempMap
- tempMap Austin 93.2 // can be
employed to insert - tempMap.insert( pairltstring,doublegt(
Chicago, 84.6 ) ) - tempMap Chicago 86.8 // is better
for update - mapltstring, double, lessltstringgt gtiterator
k - for ( k tempMap.begin() k !
tempMap.end() k ) - if ( (k).first Austin ) (k).second
97.4 -
- k tempMap.find( Austin )
- if ( k ! tempMap.end() ) (k).second 95.3
22Data Insertion to STL Containers Copy
- listpush_back(objA) mapinsert(objB)
- What actually saved in containers are copies, not
original object - Thus, each insertion incurs an object copying
procedure - If a data type is too complex, sometimes it is
better to save the pointers to the objects
23 empty() vs. size() 0
- Two methods to check if a container is empty
- empty(), takes constant time
- Check if size() 0, may take linear time!
24Container Adaptors
- stack
- stacklt vectorltTgt gt
- stacklt listltTgt gt
- queue
- queuelt dequeltTgt gt
- priority_queue
- priority_queuelt vectorltintgt, lessltintgt gt
25STL Algorithms
- Many generic algorithms
- for_each()
- find()
- count(), count_if()
- copy(), swap(), replace(), remove(), merge()
- sort(), nth_element()
- min(), max()
- partition()
-
26Algorithm Example remove()
- includeltvector.hgt
- includeltalgorithm.hgt
-
- vectorltintgt v
- v.reserve(10)
- for ( int j 1 j lt 10 j )
- v.push_back(j)
-
- cout ltlt v.size() // print 10
- v3 v5 v9 99
- remove( v.begin(), v.end(), 99 ) // remove
all element 99 - cout ltlt v.size() // still print 10!
27The Myth of remove()
At beginning
1
3
5
7
10
9
8
4
2
6
After change data
1
3
5
7
99
9
8
99
2
99
v.end()
After remove()
1
3
7
9
99
9
8
5
2
8
remove() returns an iterator
28Make remove() More Meaningful
- includeltvector.hgt
- includeltalgorithm.hgt
-
- vectorltintgt v
- v.reserve(10)
- for ( int j 1 j lt 10 j )
- v.push_back(j)
-
- cout ltlt v.size() // print 10
- v3 v5 v9 99
- v.erase( remove( v.begin(), v.end(), 99 ),
v.end() ) - cout ltlt v.size() // now print 7!
29What Else for STL?
- Many other features
- Internal implementation
- Suggestion
- Buy an STL book
- Use it as a dictionary
30Something About C
- A nice book
- Effective C, Scott Meyers, Addison-Wesley,
1998
31Data Organization in Declaring Class
- class node
- private
- double rat
- long x, y
- double cap
- long ID
- node parent
-
- class node
- private
- long x, y, ID
- double rat, cap
- node parent
-
-
- // Put member variables of
- // same type together, this
- // improves memory efficiency
32Prefer Initialization to Assignment in
Constructors
- class node
- private
- const int ID
- long x, y
- node parent
- nodenode( int j, long a, long b) ID(j),
x(a), y(b) - nodenode( int j, long a, long b) ID(j)
- x a
- y b
-
- const or reference member variables have to be
initialized - Initialization is always performed (to certain
default value), even you do the assignment later - List members in an initialization list in the
same order in which they are declared
33Inline Function
- class node
-
- long getID()
-
- long nodegetID()
- return ID
- class node
-
- inline long getID()
- return ID
-
Inline function usually runs faster But,
compiling time may be longer
34Minimize Compiling Dependencies
- // This is file A.h, class typeB is
- // declared in file B.h
- include ltB.hgt
- class typeA
-
- typeB memberB
- inline void do()
- memberB-gtdoSome()
-
-
- // Change of A.h involves B.h
- // thus, compiling time is long
- // This is file A.h, class typeB is
- // declared in file B.h
- class typeB
- class typeA
-
- typeB memberB
- void do()
-
35Prefer Pass-by-Reference to Pass-by-Value
- class tree
-
- node root
- node getRoot()
-
- // For a complex data type
- // return value takes time
- // on copying
-
- class node
-
- node root
- node getRoot()
-
- // Pass reference is faster
- // but, sometimes you have to
- // pass value
36Never Return Reference to Local Variable
- node someClassdoSomething()
-
-
- node localNode
-
- return localNode // This causes trouble!
- // Since the local
variable is discarded - // at the exit of
the function