Jianghu STLintro
Jianghu STLintro
1
What Is STL?
C++ based implementations of general
purpose data structures and algorithms
2
When 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
3
Assumption
You know basics of
C++
Data structures such as link list, hash table,
binary search tree …
Algorithms such as sorting …
4
Bottom 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
5
Example of class
class node { node::node(long id) : x(0),
private: y(0), ID(id), parent(NULL) {}
long x, y, ID;
double rat, cap; long node::getID()
node* parent; { return ID; }
public: main()
node(long id); {
void setCoordinates( long, node myNode(1);
long ); myNode.setCoordinates(5,8);
long getID(); long p = myNode.getID();
}; }
6
STL Containers
Sequence containers
vector
deque
list
Sorted associative containers
set
multiset
map
multimap
7
STL list
list is a list
Functionally, similar to double-linked list
Supports
Insertion
Deletion
Sorting
……
8
Example of list
#include <list.h>
void doSomething()
{
list<node> 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
……
}
9
STL iterator
begin()
list end()
#include <list.h>
void doSomething()
{
list<node> nodeList;
list<node>::iterator j; // Generalized pointer
……
for ( j = nodeList.begin(); j != nodeList.end(); j++ ) {
if ( (*j).getID() > 3 ) break;
}
……
}
10
insert(), erase() and remove()
#include <list.h>
void doSomething()
{
list<node> nodeList;
list<node>::iterator j; // Generalized pointer
……
for ( j = nodeList.begin(); j != nodeList.end(); j++ ) {
if ( (*j).getID() > 3 ) nodeList.insert( j, node(2) );
if ( (*j).getID() < 0 ) nodeList.erase( j ); // problem??
}
nodeList.remove( nodeA ); // operator== defined for node
……
}
11
Careful erase in a loop
#include <list.h>
void doSomething()
{
list<node> nodeList;
list<node>::iterator j, k;
……
j = nodeList.begin();
while ( j != nodeList.end() ) {
k = j++;
if ( (*k).getID() < 0 ) {
nodeList.erase( k );
}
}
……
}
12
front() and back()
#include <list.h>
void doSomething()
{
list<node> 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
……
}
13
size(), sort() and merge()
#include <list.h>
void doSomething()
{
list<node> listA, listB;
……
int numNodes = listA.size(); // number of elements in list
listA.sort(); // operator< is defined for node
listB.sort();
listA.merge( listB ); // both lists should be sorted
// listB becomes empty after merge
……
}
14
STL vector
Functionality-wise, roughly a subset of list
No push_front(), pop_front(), remove(),
sort(), merge()
Supports operator [], such as vectorA[3]
Then why need vector ?
Faster access if the data are mostly static or
not much insertion/deletion
15
STL deque
Very similar to vector, except
Supports push_front() and pop_front()
No operator []
Also friendly to accessing static data
16
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
17
Use 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:
vector<node> nodeVec;
const int a = 2;
nodeVec.reserve( a*k );
18
Sequence 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
19
Sorted Associative Containers
set<key> : a set of sorted key which can
be any data type with operator< defined
multiset<key> : allow duplicative keys
map<key, T> : T is a certain data type, the
data are always sorted according to their
keys
multimap<key, T> : allow duplicative
keys
Internally, implemented via red-black tree
20
STL map
#include <map.h>
void doSomething()
{
map<string, double, less<string> > tempMap;
tempMap[ “Austin” ] = 93.2; // [] can be employed to insert
tempMap.insert( pair<string,double>( “Chicago”, 84.6 ) );
tempMap[ “Chicago” ] = 86.8; // [] is better for update
map<string, double, less<string> >::iterator k;
22
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!
23
Container Adaptors
stack
stack< vector<T> >
stack< list<T> >
queue
queue< deque<T> >
priority_queue
priority_queue< vector<int>, less<int> >
24
STL Algorithms
Many generic algorithms
for_each()
find()
count(), count_if()
copy(), swap(), replace(), remove(), merge()
sort(), nth_element()
min(), max()
partition()
……
25
Algorithm Example remove()
#include<vector.h>
#include<algorithm.h>
……
vector<int> v;
v.reserve(10);
for ( int j = 1; j <= 10; j++ ) {
v.push_back(j);
}
cout << v.size(); // print 10
v[3] = v[5] = v[9] = 99;
remove( v.begin(), v.end(), 99 ); // remove all element == 99
cout << v.size(); // still print 10!
26
The Myth of remove()
At beginning
1 2 3 4 5 6 7 8 9 10
1 2 3 99 5 99 7 8 9 99
1 2 3 5 7 8 9 8 9 99
28
What Else for STL?
Many other features
Internal implementation
Suggestion:
Buy an STL book
Use it as a dictionary
29
Something About C++
A nice book
Effective C++, Scott Meyers, Addison-Wesley,
1998
30
Data Organization in Declaring
Class
class node { class node {
private: private:
double rat; long x, y, ID;
long x, y; double rat, cap;
double cap; node* parent;
long ID; ……
node* parent; };
……
}; // Put member variables of
// same type together, this
// improves memory efficiency
31
Prefer Initialization to
Assignment in Constructors
class node { node::node( int j, long a, long b) : ID(j),
private: x(a), y(b) { }
const int ID;
long x, y; node::node( int j, long a, long b) : ID(j) {
node* parent; x = a;
y = b;
};
}
long node::getID()
{ return ID; }
33
Minimize Compiling
Dependencies
// This is file A.h, class typeB is // This is file A.h, class typeB is
// declared in file B.h // declared in file B.h
#include <B.h>
class typeA { class typeB;
…… class typeA {
typeB* memberB; ……
inline void do() { typeB* memberB;
memberB->doSome(); void do();
} };
};
// Change of A.h involves B.h
// thus, compiling time is long
34
Prefer Pass-by-Reference to Pass-
by-Value
class tree { class node {
…… ……
node root; node root;
node getRoot(); node& getRoot();
}; };
// For a complex data type // Pass reference is faster
// return value takes time // but, sometimes you have to
// on copying // pass value
35
Never Return Reference to Local
Variable
node& someClass::doSomething()
{
……
node localNode;
……
return localNode; // This causes trouble!
// Since the local variable is discarded
// at the exit of the function
}
36