Date post: | 17-Jan-2018 |
Category: |
Documents |
Upload: | griselda-maxwell |
View: | 226 times |
Download: | 0 times |
STL Containers Inside
Peter Sikachev
Institute of Computer Graphics and Algorithms
Vienna University of Technology
Peter Sikachev 2
OverviewIntroductionIteratorsvectorlistset and mapPerformance Overview
Peter Sikachev 3
What is a Container?
Container is a class, a data structure, or an abstract data type whose instances are collections of other objects
Peter Sikachev 4
What is a Container?
Container is a class, a data structure, or an abstract data type whose instances are collections of other objects
std::vector<int> vecNumbers;
contiguous memory•vector•string•deque…
associative•set, map•multiset, multimap•hash_set…
Peter Sikachev 5
Types of the ContainersContainers
lists•list…
Peter Sikachev 6
Iterator
Iterator is an object that allows a programmer to traverse through all the elements of a collection, regardless of its specific implementation
Peter Sikachev 7
IteratorIterator
vector
elem elem
for (int* i = &Number[0]; i < &Number + Number.size(); i++){
*i = …;}
Peter Sikachev 8
IteratorIterator
vector
for (std::vector<int>::iterator i = Numbers.begin(); i < Numbers.end(); i++){
*i = …;}
elem elem
Peter Sikachev 9
IteratorIterator
vector list
for (std::list<int>::iterator i = Numbers.begin(); i < Numbers.end(); i++){
*i = …;}
nextprev
elem
nextprev
elemelem elem
Peter Sikachev 10
IteratorIterator
for (std::set<int>::iterator i = Numbers.begin(); i < Numbers.end(); i++){
*i = …;}
vector setlist
Peter Sikachev 11
Iterator CategoriesIterators
inputx=*i, ++
outputx=*i, ++
forward
bidirectional--
random acess+n, -n, += n, -= n, <, >, <=, >=
Peter Sikachev 12
Iterator Adapters•Insert•Reverse•Stream (for input and output)
Peter Sikachev 13
Iterator Adapters•Insert•Reverse•Stream (for input and output)
Peter Sikachev 14
Insertervalues
results
1 2 3
… … … …
Peter Sikachev 15
Inserter
int MultiplyByTen(int x);
vector <int> values;…vector <int> results;transform(values.begin(), values.end(),
results.end(), transmogrify);
values
results
1 2 3
… … … …
Peter Sikachev 16
Inserter
int MultiplyByTen(int x);
vector <int> values;…vector <int> results;transform(values.begin(), values.end(),
results.end(), transmogrify);
values
results
1 2 3
… … … …
Runtime error!
Peter Sikachev 17
Inserter
int MultiplyByTen(int x);
vector <int> values;…vector <int> results;transform(values.begin(), values.end(),
back_inserter(results), transmogrify);
values
results
1 2 3
… … … … 10 20 30
Peter Sikachev 18
Inserter
int MultiplyByTen(int x);
vector <int> values;…list <int> results;transform(values.begin(), values.end(),
front_inserter(results), transmogrify);
values
results
1 2 3
… … … …102030
Peter Sikachev 19
Inserter
int MultiplyByTen(int x);
vector <int> values;…list <int> results;transform(values.rbegin(), values.rend(),
front_inserter(results), transmogrify);
values
results
1 2 3
… … … …302010
Peter Sikachev 20
Inserter
int MultiplyByTen(int x);
vector <int> values;…vector <int> results;transform(values.begin(), values.end(),
inserter(results, results.begin() + results.size() / 2), transmogrify);
values
results
1 2 3
… … … …302010
Peter Sikachev 21
vector•“Growing Array”
elem elemelem
vecNumbers.size();
vecNumbers.capacity();
Costs•Find – O(n)•Insert – O(n)•Random Access – O(1)•Erase – O(n)
Peter Sikachev 22
vector•“Growing Array”
elem elemelem
vecNumbers.size();
vecNumbers.capacity();
std::vector<int> vecNumbers;int k;…vecNumbers.push_back(k);
elem
Peter Sikachev 23
vector•“Growing Array”
elem elemelem
vecNumbers.size();
vecNumbers.capacity();
std::vector<int> vecNumbers;int k;…vecNumbers.push_back(k);
elem elem
Peter Sikachev 24
vector•“Growing Array”
elem elemelem
vecNumbers.size();
vecNumbers.capacity();
std::vector<int> vecNumbers;int k;…vecNumbers.push_back(k);
elem elem elem
Peter Sikachev 25
vector•“Growing Array”
elem elemelem
vecNumbers.size();
vecNumbers.capacity();
std::vector<int> vecNumbers;int k;…vecNumbers.push_back(k);
elem elem elem
What next?
Peter Sikachev 26
vector•Reallocation•New size may vary (typically 1.5-2 old size)•Problems?
elem elemelem elem elem elem elem
Peter Sikachev 27
Reallocation Problems•Copying (copy constructors)•Iterators invalidation•Unused capacity
Peter Sikachev 28
Avoiding Reallocationsstd::vector<int> vecNumbers;for (int i = 0; i < 1000; i++){
vecNumbers.push_back(…);}
Peter Sikachev 29
Avoiding Reallocationsstd::vector<int> vecNumbers;for (int i = 0; i < 1000; i++){
vecNumbers.push_back(i);}
Up to 18 reallocations!
Peter Sikachev 30
Avoiding Reallocationsstd::vector<int> vecNumbers;vecNumbers.reserve(1000);for (int i = 0; i < 1000; i++){
vecNumbers.push_back(i);}
Peter Sikachev 31
Unused Capacity
{vector<int>(vecNumbers.begin(),vecNumbers.end()).swap(vecNumbers);
}
•“The swap trick”
Peter Sikachev 32
“Swap Trick” Step-by-Step
{vector<int>(vecNumbers.begin(),vecNumbers.end()).swap(vecNumbers);
}
•Create temporary object
Peter Sikachev 33
“Swap Trick” Step-by-Step
{vector<int>(vecNumbers.begin(),vecNumbers.end()).swap(vecNumbers);
}
•Create temporary object•Initialize with the old vector values
Peter Sikachev 34
“Swap Trick” Step-by-Step
{vector<int>(vecNumbers.begin(),vecNumbers.end()).swap(vecNumbers);
}
•Create temporary object•Initialize with the old vector values•Swap pointers
Peter Sikachev 35
“Swap Trick” Step-by-Step
{vector<int>(vecNumbers.begin(),vecNumbers.end()).swap(vecNumbers);
}
•Create temporary object•Initialize with the old vector values•Swap pointers•Delete old vector
Peter Sikachev 36
Removing the Elements•It should be straightforward, isn’t it?
Peter Sikachev 37
Removing the Elements•It should be straightforward, isn’t it?
•No, it isn’t!
Peter Sikachev 38
Removing the Elementsvector <int> v;v.reserve(10);for (int i = 1; i <= 10; i++){
v.push_back(i);}
v[3] = v[5] = v[9] = 99;
remove(v.begin(), v.end(), 99);
Peter Sikachev 39
Removing the Elementsvector <int> v;v.reserve(10);for (int i = 1; i <= 10; i++){
v.push_back(i);}
v[3] = v[5] = v[9] = 99;
remove(v.begin(), v.end(), 99);
991 2 3 5 99 7 8 9 99
v.begin() v.end()
Peter Sikachev 40
Removing the Elementsvector <int> v;v.reserve(10);for (int i = 1; i <= 10; i++){
v.push_back(i);}
v[3] = v[5] = v[9] = 99;
vector <int>::iterator newEnd(remove(v.begin(), v.end(), 99));
51 2 3 7 8 9 ? ? ?
v.begin() v.end()
newEnd
Peter Sikachev 41
Removing the Elementsvector <int> v;v.reserve(10);for (int i = 1; i <= 10; i++){
v.push_back(i);}
v[3] = v[5] = v[9] = 99;
remove(v.begin(), v.end(), 99);
51 2 3 7 8 9 8 9 99
v.begin() v.end()
Peter Sikachev 42
Removing the Elementsvector <int> v;v.reserve(10);for (int i = 1; i <= 10; i++){
v.push_back(i);}
v[3] = v[5] = v[9] = 99;
v.erase(remove(v.begin(), v.end(), 99),v.end());
51 2 3 7 8 9
v.begin() v.end()
Peter Sikachev 43
list•just a list (hence the name!)
Costs•Find – O(n)•Insert – O(1)•Random Access – O(n)•Erase – O(1)
nextprev
elem
nextprev
elem
Peter Sikachev 44
Checking the Emptinessif (c.size() == 0)… if (c.empty())…
Peter Sikachev 45
Checking the Emptinessif (c.size() == 0)… if (c.empty())…
bad good
Peter Sikachev 46
Checking the Emptinessif (c.size() == 0)… if (c.empty())…
bad – O(n) good – O(1)
Peter Sikachev 47
Why?list <int> list1;list <int> list2;…list1.splice(
list1.end(), list2,find(list2.begin(), list2.end(), 5),find(list2.rbegin(), list2.rend(), 10).base()
);
/*move all nodes in list2 from the first occurrence of 5 through the last occurrence of 10 to the end of list1. “base()” converts a reverse_iterator into the “corresponding” iterator*/
Peter Sikachev 48
Why?list <int> list1;list <int> list2;…list1.splice(
list1.end(), list2,find(list2.begin(), list2.end(), 5),find(list2.rbegin(), list2.rend(), 10).base()
);
/*move all nodes in list2 from the first occurrence of 5 through the last occurrence of 10 to the end of list1. “base()” converts a reverse_iterator into the “corresponding” iterator*/
size unknown!
Peter Sikachev 49
set and map•Organized as a binary search tree
•node.value > node.leftSubtree.values•node.value < node.rightSubtree.values•both the left and right subtrees must also be binary search trees.
Costs•Find – O(log(n))•Insert – O(log(n))•Random Access(?) – O(log(n))•Erase – O(log(n))
Peter Sikachev 50
Inserting a new element
1
Peter Sikachev 51
Inserting a new element
1
2
Peter Sikachev 52
Inserting a new element
1
2
3
Peter Sikachev 53
Inserting a new element
1
2
3
4
Peter Sikachev 54
Inserting a new element
1
2
3
4
5
Peter Sikachev 55
Inserting a new element
1
2
3
4
5
6
Costs•Find – O(n)•Insert – O(n)•Random Access(?) – O(n)•Erase – O(n)
•Limiting subtree height is needed
Peter Sikachev 56
Red-Black Tree
1. A node is either red or black.2. The root is black.3. All leaves are black.4. Both children of every red node are black.5. Every simple path from a given node to any of its descendant
leaves contains the same number of black nodes.
=> height < 2 lg (n+1)
Peter Sikachev 57
Red-Black Tree
• New element added is red• Adding may violate ONLY rules 2 and 4• Rule 2 => just repaint• Otherwise…
Peter Sikachev 58
Red-Black Tree• Case 1
• Case 2(after that apply 3)
• Case 3
• The similar stuff for deleting
Peter Sikachev 59
Consequences• No key modifications in place!