KEMBAR78
C++ STL Complete Study Guide | PDF | C++ | Algorithms And Data Structures
0% found this document useful (0 votes)
15 views18 pages

C++ STL Complete Study Guide

The document is a comprehensive study guide on the C++ Standard Template Library (STL), detailing its components such as containers, iterators, algorithms, function objects, and utilities. It covers various types of containers including sequence, associative, and unordered containers, along with their operations and performance characteristics. Additionally, it discusses algorithms for modifying and non-modifying operations, as well as performance comparisons for different container types.

Uploaded by

vadersback04
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views18 pages

C++ STL Complete Study Guide

The document is a comprehensive study guide on the C++ Standard Template Library (STL), detailing its components such as containers, iterators, algorithms, function objects, and utilities. It covers various types of containers including sequence, associative, and unordered containers, along with their operations and performance characteristics. Additionally, it discusses algorithms for modifying and non-modifying operations, as well as performance comparisons for different container types.

Uploaded by

vadersback04
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 18

C++ STL (Standard Template Library) Complete Study Guide

1. STL Overview

What is STL?
The Standard Template Library is a collection of template classes and functions that provide:

Containers: Data structures to store collections of objects

Iterators: Objects that point to elements in containers


Algorithms: Functions that perform operations on containers

Function Objects: Classes that act like functions

Adaptors: Components that modify the interface of other components

Key Benefits
Generic Programming: Works with any data type

Efficiency: Highly optimized implementations


Standardized: Consistent across different compilers

Reusability: No need to implement common data structures

2. Containers

2.1 Sequence Containers

Vector

Dynamic array that can grow/shrink at runtime.

cpp
#include <vector>
vector<int> vec = {1, 2, 3, 4, 5};

// Basic operations
vec.push_back(6); // Add to end: O(1) amortized
vec.pop_back(); // Remove from end: O(1)
vec.insert(vec.begin() + 2, 10); // Insert at position: O(n)
vec.erase(vec.begin() + 1); // Remove at position: O(n)

// Access
int val = vec[2]; // Direct access: O(1)
int val2 = vec.at(2); // Bounds-checked access: O(1)
int front = vec.front(); // First element: O(1)
int back = vec.back(); // Last element: O(1)

// Size operations
vec.size(); // Current size
vec.capacity(); // Current capacity
vec.reserve(100); // Reserve space for 100 elements
vec.resize(10); // Resize to 10 elements

Deque (Double-ended Queue)

Allows fast insertion/deletion at both ends.

cpp

#include <deque>
deque<int> dq = {1, 2, 3};

dq.push_front(0); // Add to front: O(1)


dq.push_back(4); // Add to back: O(1)
dq.pop_front(); // Remove from front: O(1)
dq.pop_back(); // Remove from back: O(1)

// Random access like vector


int val = dq[1]; // O(1) access

List (Doubly Linked List)

Efficient insertion/deletion anywhere in the container.

cpp
#include <list>
list<int> lst = {1, 2, 3, 4};

lst.push_front(0); // Add to front: O(1)


lst.push_back(5); // Add to back: O(1)
lst.insert(next(lst.begin(), 2), 10); // Insert at position: O(1)
lst.remove(3); // Remove all occurrences of 3: O(n)
lst.sort(); // Sort the list: O(n log n)
lst.unique(); // Remove consecutive duplicates: O(n)

Forward List (Singly Linked List)

More memory-efficient than list, but only forward iteration.

cpp

#include <forward_list>
forward_list<int> flst = {1, 2, 3};

flst.push_front(0); // Add to front: O(1)


flst.insert_after(flst.begin(), 5); // Insert after position: O(1)
flst.remove(2); // Remove all occurrences: O(n)

Array (Fixed-size Array)

Fixed-size array with STL container interface.

cpp

#include <array>
array<int, 5> arr = {1, 2, 3, 4, 5};

arr[2] = 10; // Direct access


arr.at(1) = 20; // Bounds-checked access
arr.fill(0); // Fill all elements with 0

2.2 Associative Containers

Set

Stores unique elements in sorted order.

cpp
#include <set>
set<int> s = {3, 1, 4, 1, 5}; // Duplicates automatically removed

s.insert(2); // Insert element: O(log n)


s.erase(1); // Remove element: O(log n)

// Search operations
auto it = s.find(3); // Find element: O(log n)
if (it != s.end()) {
cout << "Found: " << *it;
}

bool exists = s.count(4); // Check existence: O(log n)


auto lower = s.lower_bound(3); // First element >= 3: O(log n)
auto upper = s.upper_bound(3); // First element > 3: O(log n)

Multiset

Like set but allows duplicate elements.

cpp

#include <set>
multiset<int> ms = {1, 2, 2, 3, 3, 3};

ms.insert(2); // Insert (duplicates allowed)


int count = ms.count(2); // Count occurrences: O(log n + k)
ms.erase(ms.find(2)); // Remove single occurrence
ms.erase(2); // Remove all occurrences

Map

Stores key-value pairs with unique keys in sorted order.

cpp
#include <map>
map<string, int> m = {{"apple", 5}, {"banana", 3}};

m["orange"] = 7; // Insert/update: O(log n)


m.insert({"grape", 4}); // Alternative insert
m.erase("banana"); // Remove by key: O(log n)

// Access
int val = m["apple"]; // Direct access (creates if not exists)
int val2 = m.at("apple"); // Bounds-checked access

// Search
auto it = m.find("grape"); // Find by key: O(log n)
if (it != m.end()) {
cout << it->first << ": " << it->second;
}

Multimap

Like map but allows duplicate keys.

cpp

#include <map>
multimap<string, int> mm;

mm.insert({"fruit", 1});
mm.insert({"fruit", 2}); // Duplicate keys allowed

auto range = mm.equal_range("fruit"); // Get range of elements with key


for (auto it = range.first; it != range.second; ++it) {
cout << it->second << " ";
}

2.3 Unordered Associative Containers (C++11)

Unordered Set

Hash table implementation of set.

cpp
#include <unordered_set>
unordered_set<int> us = {1, 2, 3, 4, 5};

us.insert(6); // Insert: O(1) average, O(n) worst


us.erase(3); // Remove: O(1) average, O(n) worst
bool found = us.find(4) != us.end(); // Find: O(1) average

// Hash table info


cout << "Bucket count: " << us.bucket_count() << endl;
cout << "Load factor: " << us.load_factor() << endl;

Unordered Map

Hash table implementation of map.

cpp

#include <unordered_map>
unordered_map<string, int> um = {{"key1", 10}, {"key2", 20}};

um["key3"] = 30; // Insert/update: O(1) average


um.erase("key1"); // Remove: O(1) average

auto it = um.find("key2"); // Find: O(1) average


if (it != um.end()) {
cout << it->first << ": " << it->second;
}

2.4 Container Adaptors

Stack (LIFO)

cpp
#include <stack>
stack<int> stk;

stk.push(1); // Push element


stk.push(2);
stk.push(3);

while (!stk.empty()) {
cout << stk.top() << " "; // Access top element
stk.pop(); // Remove top element
}

Queue (FIFO)

cpp

#include <queue>
queue<int> q;

q.push(1); // Add to back


q.push(2);
q.push(3);

while (!q.empty()) {
cout << q.front() << " "; // Access front element
q.pop(); // Remove front element
}

Priority Queue (Max Heap by default)

cpp
#include <queue>
priority_queue<int> pq; // Max heap
priority_queue<int, vector<int>, greater<int>> min_pq; // Min heap

pq.push(3);
pq.push(1);
pq.push(4);

while (!pq.empty()) {
cout << pq.top() << " "; // Access max element
pq.pop(); // Remove max element
}
// Output: 4 3 1

3. Iterators

Iterator Types

cpp

vector<int> vec = {1, 2, 3, 4, 5};

// Forward iterator
vector<int>::iterator it = vec.begin();
while (it != vec.end()) {
cout << *it << " ";
++it;
}

// Reverse iterator
vector<int>::reverse_iterator rit = vec.rbegin();
while (rit != vec.rend()) {
cout << *rit << " ";
++rit;
}

// Const iterator
vector<int>::const_iterator cit = vec.cbegin();
// *cit = 10; // Error: cannot modify through const iterator

Iterator Operations

cpp
vector<int> vec = {1, 2, 3, 4, 5};
auto it = vec.begin();

// Basic operations
*it; // Dereference
++it; // Move to next
--it; // Move to previous (bidirectional+)
it + 3; // Jump ahead 3 positions (random access)
it - 2; // Jump back 2 positions (random access)

// Helper functions
advance(it, 3); // Move iterator 3 positions forward
auto dist = distance(vec.begin(), vec.end()); // Calculate distance
auto next_it = next(it, 2); // Get iterator 2 positions ahead
auto prev_it = prev(it, 1); // Get iterator 1 position back

4. Algorithms

4.1 Non-modifying Algorithms

cpp

#include <algorithm>
vector<int> vec = {1, 2, 3, 4, 5, 3, 6};

// Search algorithms
auto it = find(vec.begin(), vec.end(), 3); // Find first occurrence
auto it2 = find_if(vec.begin(), vec.end(), [](int x) { return x > 3; }); // Find with condition

// Count algorithms
int count = count(vec.begin(), vec.end(), 3); // Count occurrences
int count_if = count_if(vec.begin(), vec.end(), [](int x) { return x > 3; }); // Count with condition

// Check algorithms
bool all_positive = all_of(vec.begin(), vec.end(), [](int x) { return x > 0; });
bool any_even = any_of(vec.begin(), vec.end(), [](int x) { return x % 2 == 0; });
bool none_negative = none_of(vec.begin(), vec.end(), [](int x) { return x < 0; });

// For each
for_each(vec.begin(), vec.end(), [](int& x) { cout << x << " "; });

4.2 Modifying Algorithms


cpp

vector<int> vec = {1, 2, 3, 4, 5};


vector<int> dest(5);

// Copy algorithms
copy(vec.begin(), vec.end(), dest.begin()); // Copy all elements
copy_if(vec.begin(), vec.end(), dest.begin(), [](int x) { return x > 2; }); // Copy with condition

// Transform
vector<int> result(vec.size());
transform(vec.begin(), vec.end(), result.begin(), [](int x) { return x * 2; }); // Square each element

// Fill and generate


fill(vec.begin(), vec.end(), 10); // Fill with value 10
generate(vec.begin(), vec.end(), []() { return rand() % 100; }); // Generate random values

// Replace
replace(vec.begin(), vec.end(), 3, 30); // Replace all 3s with 30s
replace_if(vec.begin(), vec.end(), [](int x) { return x > 5; }, 0); // Replace based on condition

4.3 Sorting and Related

cpp

vector<int> vec = {5, 2, 8, 1, 9, 3};

// Sorting
sort(vec.begin(), vec.end()); // Ascending sort
sort(vec.begin(), vec.end(), greater<int>()); // Descending sort
sort(vec.begin(), vec.end(), [](int a, int b) { return abs(a) < abs(b); }); // Custom comparator

// Partial sorting
partial_sort(vec.begin(), vec.begin() + 3, vec.end()); // Sort first 3 elements
nth_element(vec.begin(), vec.begin() + 2, vec.end()); // Put 3rd smallest at position 2

// Binary search (requires sorted container)


bool found = binary_search(vec.begin(), vec.end(), 5);
auto lower = lower_bound(vec.begin(), vec.end(), 5);
auto upper = upper_bound(vec.begin(), vec.end(), 5);

4.4 Set Operations (on sorted ranges)


cpp

vector<int> v1 = {1, 2, 3, 4, 5};


vector<int> v2 = {3, 4, 5, 6, 7};
vector<int> result;

// Set union
set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), back_inserter(result));

// Set intersection
result.clear();
set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), back_inserter(result));

// Set difference
result.clear();
set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), back_inserter(result));

4.5 Heap Operations

cpp

vector<int> vec = {3, 1, 4, 1, 5, 9, 2, 6};

// Make heap
make_heap(vec.begin(), vec.end()); // Create max heap

// Heap operations
push_heap(vec.begin(), vec.end()); // Add element to heap
pop_heap(vec.begin(), vec.end()); // Move max to end
vec.pop_back(); // Remove the max element

// Sort heap
sort_heap(vec.begin(), vec.end()); // Convert heap to sorted array

5. Function Objects (Functors)

Built-in Function Objects

cpp
#include <functional>

// Arithmetic
plus<int> add;
int result = add(5, 3); // 8

minus<int> subtract;
multiplies<int> multiply;
divides<int> divide;

// Comparison
greater<int> gt;
bool result = gt(5, 3); // true

less<int> lt;
equal_to<int> eq;
not_equal_to<int> neq;

// Logical
logical_and<bool> and_op;
logical_or<bool> or_op;
logical_not<bool> not_op;

Lambda Expressions (C++11)

cpp

// Basic lambda
auto lambda = [](int x) { return x * x; };
int result = lambda(5); // 25

// Lambda with capture


int multiplier = 10;
auto multiply_by = [multiplier](int x) { return x * multiplier; };

// Capture by reference
int counter = 0;
auto increment = [&counter]() { counter++; };

// Generic lambda (C++14)


auto generic = [](auto x, auto y) { return x + y; };
6. Adaptors and Utilities

Iterator Adaptors

cpp

#include <iterator>

vector<int> vec;

// Insert iterators
back_insert_iterator<vector<int>> back_it = back_inserter(vec);
front_insert_iterator<deque<int>> front_it = front_inserter(deq);
insert_iterator<set<int>> ins_it = inserter(s, s.begin());

// Stream iterators
istream_iterator<int> input_it(cin);
ostream_iterator<int> output_it(cout, " ");

Utility Functions

cpp

#include <utility>

// Pair
pair<int, string> p = make_pair(1, "hello");
cout << p.first << " " << p.second;

// Tuple (C++11)
#include <tuple>
tuple<int, double, string> t = make_tuple(1, 3.14, "world");
cout << get<0>(t) << " " << get<1>(t) << " " << get<2>(t);

// Move semantics (C++11)


vector<int> v1 = {1, 2, 3};
vector<int> v2 = move(v1); // v1 is now empty, v2 has the data

7. Performance Comparison

Time Complexities
Container Access Insert Delete Search

vector O(1) O(n) O(n) O(n)

deque O(1) O(n) O(n) O(n)

list O(n) O(1) O(1) O(n)

set/map O(log n) O(log n) O(log n) O(log n)

unordered_set/map O(1) avg O(1) avg O(1) avg O(1) avg

When to Use What


vector: Default choice, fast random access, cache-friendly
deque: Need fast insertion at both ends
list: Frequent insertion/deletion in middle

set/map: Need sorted data with fast search


unordered_set/map: Need fastest possible search/insert

8. Best Practices

Container Selection
1. Use vector by default
2. Use deque if you need fast front insertion
3. Use list for frequent middle insertion/deletion

4. Use map/set when you need sorted data

5. Use unordered_map/unordered_set for fastest lookups

Performance Tips

cpp
// Reserve space for vectors when size is known
vector<int> vec;
vec.reserve(1000);

// Use emplace instead of insert for complex objects


vector<pair<int, string>> vec;
vec.emplace_back(1, "hello"); // Better than vec.push_back(make_pair(1, "hello"))

// Use const iterators when not modifying


for (auto cit = vec.cbegin(); cit != vec.cend(); ++cit) {
cout << *cit;
}

// Prefer range-based for loops (C++11)


for (const auto& element : container) {
cout << element;
}

Memory Management

cpp

// Clear vs shrink_to_fit
vector<int> vec(1000);
vec.clear(); // Size = 0, but capacity unchanged
vec.shrink_to_fit(); // Reduce capacity to match size

// Swap trick (pre-C++11)


vector<int>().swap(vec); // Clear and deallocate memory

9. Common Patterns and Idioms

Erase-Remove Idiom

cpp

vector<int> vec = {1, 2, 3, 2, 4, 2, 5};


// Remove all occurrences of 2
vec.erase(remove(vec.begin(), vec.end(), 2), vec.end());

Sort with Custom Comparator

cpp
vector<pair<int, string>> vec = {{3, "apple"}, {1, "banana"}, {2, "cherry"}};
// Sort by first element
sort(vec.begin(), vec.end());
// Sort by string length
sort(vec.begin(), vec.end(), [](const auto& a, const auto& b) {
return a.second.length() < b.second.length();
});

Finding Min/Max Elements

cpp

vector<int> vec = {3, 1, 4, 1, 5, 9};


auto min_it = min_element(vec.begin(), vec.end());
auto max_it = max_element(vec.begin(), vec.end());
auto minmax_pair = minmax_element(vec.begin(), vec.end());

10. Advanced Topics

Custom Comparators for Containers

cpp

// Custom comparator for set


struct Compare {
bool operator()(int a, int b) const {
return a > b; // Descending order
}
};
set<int, Compare> desc_set;

// Using lambda (C++11)


auto cmp = [](int a, int b) { return a > b; };
set<int, decltype(cmp)> desc_set2(cmp);

Custom Hash Functions

cpp
struct Point {
int x, y;
};

struct PointHash {
size_t operator()(const Point& p) const {
return hash<int>()(p.x) ^ (hash<int>()(p.y) << 1);
}
};

struct PointEqual {
bool operator()(const Point& a, const Point& b) const {
return a.x == b.x && a.y == b.y;
}
};

unordered_set<Point, PointHash, PointEqual> point_set;

11. Common Mistakes and Pitfalls


1. Iterator Invalidation: Modifying containers while iterating
2. Dangling Iterators: Using iterators after container modification

3. Wrong Container Choice: Using vector when list would be better

4. Not Reserving Space: Causing unnecessary reallocations


5. Comparing Floating Point: Direct equality comparison of floats

12. Practice Problems

Beginner
1. Implement a function to find duplicates in a vector
2. Merge two sorted vectors

3. Find the kth largest element in an array


4. Implement a simple cache using map

Intermediate
1. Implement LRU cache using list and unordered_map

2. Find all anagrams in a list of strings


3. Implement a basic graph using adjacency list
4. Priority queue-based Dijkstra's algorithm

Advanced
1. Implement a custom allocator

2. Thread-safe container wrapper


3. Memory pool for frequent allocations

4. Custom iterator for tree traversal

Quick Reference

Most Common Operations

cpp

// Vector
vector<int> v = {1, 2, 3};
v.push_back(4);
v.size();
v[0];

// Map
map<string, int> m;
m["key"] = 42;
m.find("key") != m.end();

// Set
set<int> s;
s.insert(5);
s.count(5);

// Algorithm
sort(v.begin(), v.end());
auto it = find(v.begin(), v.end(), 3);

The STL is vast and powerful - master these fundamentals and gradually explore advanced features as
needed!

You might also like