STL Containers Inside Peter Sikachev Institute of Computer Graphics and Algorithms Vienna University...

Post on 17-Jan-2018

226 views 0 download

description

Peter Sikachev 2 What is a Container? Container is a class, a data structure, or an abstract data type whose instances are collections of other objects

transcript

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!