0% found this document useful (0 votes)
7 views

OOP Unit 6 Notes

SPPU

Uploaded by

harischaus
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

OOP Unit 6 Notes

SPPU

Uploaded by

harischaus
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 38

1|Page © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

Unit –VI
Standard Template Library (STL)
1. STL

1.1 Introduction to STL

The Standard Template Library (STL) in C++ is a powerful library of pre-defined classes
and functions designed to simplify programming tasks. These components provide ready-made
code for handling algorithms, data structures, and operations, regardless of the data type.

For example, sorting elements in a list is a generalized operation. The same sorting algorithm
can be applied to integers, floats, or any other data type. STL leverages generic programming
to achieve this flexibility, enabling programmers to reuse code for various data types.

Key Features of STL:

 It is a set of template classes that implement common algorithms and data structures.

 It is defined using generic programming, making it applicable to nearly all data types.

 STL provides components to focus on what operations can be performed, rather than
on the underlying data type.

Need for STL

 STL offers a vast set of template classes and functions to perform a variety of tasks.

 Its generic programming approach allows these classes and functions to operate on
different types of data.

 STL simplifies complex programming tasks, reducing both development time and
effort.

1.2 STL Components

The STL consists of three core components: Containers, Algorithms, and Iterators.

1. Containers

o Containers are objects designed to hold collections of other objects.


2|Page © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

o They provide pre-defined functions to manipulate the objects they store.

o Examples include Vector, Map, Queue, etc.

o Containers are divided into three categories:

 Sequence Containers: Maintain the order of elements (e.g., vector, list, deque).

 Associative Containers: Automatically arrange elements in sorted order (e.g., set,


map).

 Unordered Associative Containers: Use hash tables for faster access but don't
maintain order (e.g., unordered_set, unordered_map).

2. Algorithms

o The STL provides a wide range of pre-defined algorithms that can be applied to
containers, regardless of their type.

o These algorithms include operations like initialization, sorting, searching, and


transforming the contents of containers.

o Many algorithms operate on a range of elements (subsets of a container) rather than


the entire container.

o Example algorithms: sort, find, reverse, binary_search.

3. Iterators

o Iterators are objects that act like pointers to elements within a container.

o They serve as a bridge between containers and algorithms, enabling seamless traversal
and manipulation of container contents.

o Using iterators, you can cycle through the elements of a container in a specific order.

o Iterators support pointer-like operations such as incrementing (++) and decrementing


(--).

Key Advantages of STL

 Code Reusability: Generic programming allows the same algorithms to work with
various data types.
3|Page © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

 Simplifies Development: Reduces the complexity and effort required to implement


common data structures and algorithms.

 Efficiency: Pre-optimized algorithms improve runtime performance.

1.3 Containers

Containers are objects designed to hold collections of other objects, offering functionality to
store, access, and manipulate data.

Types of Containers

The STL provides three main types of containers:

1. Sequence Containers

 Description: These containers store elements in a linear order, where new elements are
added to the end of the collection.

 Examples: vector, array, list, deque, forward_list.

 Characteristics:

o Maintain the insertion order of elements.

o Support efficient traversal and access to elements.

o Commonly used for dynamic arrays, linked lists, and double-ended queues.

2. Associative Containers

 Description: These containers store elements in a sorted order, where the position of
an element is determined by its value.

 Examples: set, map, multiset, multimap.

 Characteristics:

o Provide fast retrieval of elements using keys.

o Allow automatic sorting based on values or keys.

o Efficient for tasks requiring frequent lookups, such as dictionaries and sets.

3. Unordered Associative Containers


4|Page © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

 Description: These containers store elements in an unordered manner, where the


position of elements does not depend on their value.

 Examples: unordered_set, unordered_multiset, unordered_map,


unordered_multimap.

 Characteristics:

o Use hash tables for internal organization, enabling faster access than sorted
associative containers.

o Suitable for applications where order is not important but fast lookups are essential.

Difference between Sequence Containers and Associative Containers in STL

Aspect Sequence Containers Associative Containers


Definition Stores elements in a linear sequence Stores elements in a sorted or
(order of insertion matters). hashed structure based on keys.
Order of Maintains the order of insertion. Elements are automatically
Elements ordered (sorted or hashed).
Access Method Access elements by position/index Access elements by key or iterator.
(e.g., arr[0], iterators).
Examples vector, deque, list, array, set, multiset, map, multimap,
forward_list. unordered_set, unordered_map.
Efficiency Efficient for sequential access and Optimized for searching, insertion,
dynamic resizing. and deletion based on keys.
Underlying Uses contiguous or linked memory Uses tree structures (e.g., Red-
Mechanism (depending on container). Black Tree) or hash tables.
Duplicate Allows duplicate elements (except set and map do not allow
Elements in array or fixed-size containers). duplicates; multiset and multimap
do.
Use Case Suitable for tasks requiring ordered Ideal for associative tasks like key-
data manipulation. value mapping or quick lookups
by keys.

Container Adaptors
5|Page © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

Container adaptors modify the interface of sequential containers to provide specific


behaviors.

They allow developers to use underlying containers (like vector or deque) with additional
constraints, adapting their functionality to meet specific requirements.

1. stack:

o Implements a LIFO (Last-In, First-Out) data structure.

o Operates by pushing elements onto the top and popping them off the top.

o Example Use Case: Undo functionality in text editors.

2. queue:

o Implements a FIFO (First-In, First-Out) data structure.

o Operates by adding elements to the back and removing them from the front.

o Example Use Case: Task scheduling or customer service queues.

3. priority_queue:

o Implements a data structure where elements are stored based on priority.

o The highest-priority element is always at the top.

o Example Use Case: Scheduling algorithms, such as Dijkstra's shortest path.

Container Classes in STL

Containers are collections of elements that provide common functions to manipulate and
organize data.

1. Array

 Description: Fixed-size sequence container storing elements in a strict linear sequence.


Memory allocation is fixed and cannot be resized.

 Advantage: Fast access to any nth element.

 Drawback: Allocates fixed memory, so not memory efficient.

Operations on Array:
6|Page © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

1. at(): Accesses elements with bounds checking.

2. get(): Accesses elements (overloaded from tuple).

3. operator[]: Accesses elements directly, like C-style arrays.

Example: Program to demonstrate functioning of array container

#include <iostream>
#include <array> // For std::array
using namespace std;

int main() {
// Initializing an array of fixed size
array<int, 5> arr = {10, 20, 30, 40, 50};

// Accessing elements using at()


cout << "Using at(): ";
for (int i = 0; i < arr.size(); i++) {
cout << arr.at(i) << " ";
}
cout << endl;

// Accessing elements using get()


cout << "Using get(): ";
cout << get<0>(arr) << " " << get<1>(arr) << " "
<< get<2>(arr) << " " << get<3>(arr) << " "
<< get<4>(arr) << endl;

// Accessing elements using operator[]


cout << "Using operator[]: ";
for (int i = 0; i < arr.size(); i++) {
cout << arr[i] << " ";
}
7|Page © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

cout << endl;


return 0;
}
Output:
Using at(): 10 20 30 40 50
Using get(): 10 20 30 40 50
Using operator[]: 10 20 30 40 50
2. Vector

Vectors are the most commonly used containers in STL. They are sequence containers
representing dynamic arrays that can change their size as needed. When the number of elements
exceeds its current capacity, the vector dynamically allocates additional memory to
accommodate new elements.

Advantages:

1. Automatically resizes, allowing the user to add elements without worrying about the
container size.

2. Built-in functions simplify operations, saving coding time and effort.

3. Can hold almost any type of elements, offering flexibility.

Disadvantage:

 Reallocation of memory can be time-consuming.

Creating Vector Objects:

Vectors can be defined as follows:

 vector<int> a: Defines an empty vector of int.

 vector<float> b(10): Creates a 10-element vector of float.

 vector<int> c(5, 0): Creates a 5-element vector of int with all elements initialized to 0.

 vector<int> d(a): Creates a new vector from an existing vector a.

Functions Associated with Vectors:

1. Iterator-Related Functions
8|Page © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

 begin(): Returns an iterator to the first element.

 end(): Returns an iterator to the position after the last element.

 rbegin(): Returns a reverse iterator to the last element.

 rend(): Returns a reverse iterator to the position before the first element.

 cbegin(): Returns a constant iterator to the first element.

 cend(): Returns a constant iterator to the position after the last element.

 crbegin(): Returns a constant reverse iterator to the last element.

 crend(): Returns a constant reverse iterator to the position before the first element.

2. Capacity-Related Functions

 size(): Returns the number of elements in the vector.

 max_size(): Returns the maximum number of elements the vector can hold.

 capacity(): Returns the size of the allocated storage space.

 resize(n): Resizes the vector to contain n elements.

 empty(): Checks whether the vector is empty.

 shrink_to_fit(): Reduces the vector's capacity to fit its size.

 reserve(n): Reserves storage for at least n elements.

3. Element Access Functions

 operator[]: Accesses the element at position g.

 at(g): Returns a reference to the element at position g.

 front(): Returns a reference to the first element.

 back(): Returns a reference to the last element.

 data(): Returns a pointer to the underlying array used for storage.

Example: Program to demonstrate functioning of vector container

#include <iostream>
9|Page © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

#include <vector>
using namespace std;

int main() {
// Create a vector and add elements
vector<int> vec = {1, 2, 3, 4, 5};

// Display elements using iterators


cout << "Vector elements: ";
for (auto it = vec.begin(); it != vec.end(); ++it)
cout << *it << " ";

// Access elements using at() and operator[]


cout << "\nElement at index 2 (using at): " << vec.at(2);
cout << "\nElement at index 3 (using []): " << vec[3];

// Display size and capacity


cout << "\nSize: " << vec.size() << ", Capacity: " <<
vec.capacity();

// Modify vector
vec.push_back(6);
cout << "\nAfter push_back(6), size: " << vec.size() << ",
Capacity: " << vec.capacity();

vec.pop_back();
cout << "\nAfter pop_back(), size: " << vec.size();

// Access front and back elements


cout << "\nFront: " << vec.front() << ", Back: " << vec.back();
return 0;
}
10 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

Output:
Vector elements: 1 2 3 4 5
Element at index 2 (using at): 3
Element at index 3 (using []): 4
Size: 5, Capacity: 5
After push_back(6), size: 6, Capacity: 10
After pop_back(), size: 5
Front: 1, Back: 5
3. List

Lists are sequential containers implemented as doubly-linked lists. They allow insertion and
deletion operations anywhere within the sequence and support iteration in both directions.

Advantages:

1. Memory Efficient: Suitable for frequent insertion and deletion of elements.

2. Performs better for sorting and algorithms requiring intensive element movement.

Drawbacks:

1. No Direct Access: To access the nth element, iteration is required from the current
position to the desired element.

Functions Used with List

1. Element Access:

o front(): Returns the first element.

o back(): Returns the last element.

2. Insertion and Deletion:

o push_front(g): Adds a new element g at the beginning.

o push_back(g): Adds a new element g at the end.

o pop_front(): Removes the first element.

o pop_back(): Removes the last element.

o insert(): Inserts new elements at a specified position.


11 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

o erase(): Removes a single element or a range of elements.

o remove(): Removes all elements equal to a specified value.

3. Modifiers:

o assign(): Replaces current elements with new ones and resizes the list.

o reverse(): Reverses the list.

o resize(n): Resizes the list to n elements.

o sort(): Sorts the list in increasing order.

4. Capacity and Size:

o size(): Returns the number of elements.

o empty(): Checks if the list is empty (returns true or false).

o max_size(): Returns the maximum number of elements the list can hold.

5. Iterators:

o begin(): Returns an iterator pointing to the first element.

o end(): Returns an iterator pointing to the theoretical element after the last one.

Example: Program to show the working of some functions of List

#include <iostream>
#include <list>
using namespace std;

int main() {
// Initializing a list
list<int> lst = {10, 20, 30, 40, 50};

// Displaying the list


cout << "Initial List: ";
for (auto it = lst.begin(); it != lst.end(); ++it)
cout << *it << " ";
12 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

cout << endl;

// Using push_front and push_back


lst.push_front(5);
lst.push_back(60);
cout << "After push_front(5) and push_back(60): ";
for (int x : lst)
cout << x << " ";
cout << endl;

// Using pop_front and pop_back


lst.pop_front();
lst.pop_back();
cout << "After pop_front() and pop_back(): ";
for (int x : lst)
cout << x << " ";
cout << endl;

// Using reverse
lst.reverse();
cout << "After reverse(): ";
for (int x : lst)
cout << x << " ";
cout << endl;

// Using sort
lst.sort();
cout << "After sort(): ";
for (int x : lst)
cout << x << " ";
cout << endl;
13 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

return 0;
}
4. Deque

A Deque (Double-Ended Queue) is a sequence container with dynamic sizes that allows
insertion and deletion at both ends (front and back).

 Unlike vectors, contiguous storage allocation is not guaranteed.

 Deques are more efficient for insertion and deletion of elements compared to vectors.

 They are often used to implement data structures like queues and stacks.

Characteristics of Deque:

1. Elements can be added or removed from both ends.

2. Similar to queues but supports operations at both the front and back.

3. More efficient than vectors for frequent insertions and deletions.

Advantages:

 Dynamic size adjustments.

 Efficient insertion and deletion at both ends.

Drawbacks:

 Direct memory access is not guaranteed due to non-contiguous storage.

Commonly Used Functions:

1. Insert and Access

o insert(pos, value) – Inserts an element at the specified position and returns an


iterator pointing to the newly inserted element.

o operator[] – Accesses the element at the specified position.

o at(pos) – Accesses the element at the specified position (with bounds checking).

2. Push and Pop

o push_front(value) – Adds an element at the front.


14 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

o push_back(value) – Adds an element at the back.

o pop_front() – Removes an element from the front.

o pop_back() – Removes an element from the back.

3. Iterators

o begin() – Returns an iterator pointing to the first element.

o end() – Returns an iterator pointing past the last element.

o rbegin() – Reverse iterator pointing to the last element.

o rend() – Reverse iterator pointing before the first element.

o cbegin(), cend() – Constant iterators for read-only traversal.

4. Capacity

o size() – Returns the number of elements in the deque.

o max_size() – Returns the maximum number of elements the deque can hold.

o resize(new_size) – Changes the size of the deque.

o empty() – Checks if the deque is empty.

5. Modifiers

o assign(n, value) – Replaces the contents with n elements of the given value.

o erase(pos) – Removes an element at the specified position.

o clear() – Removes all elements from the deque.

o swap(other_deque) – Swaps the contents of two deques.

o emplace_front(args...) – Constructs an element at the beginning.

o emplace_back(args...) – Constructs an element at the end.

Example: Program to show the working of some functions of deque

#include <iostream>
#include <deque>
15 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

using namespace std;

int main() {
deque<int> dq;

// Push elements to the front and back


dq.push_back(10);
dq.push_front(5);
dq.push_back(15);

cout << "Deque after push operations: ";


for (int x : dq)
cout << x << " ";
cout << endl;

// Accessing elements
cout << "Front element: " << dq.front() << endl;
cout << "Back element: " << dq.back() << endl;

// Pop elements from front and back


dq.pop_front();
dq.pop_back();

cout << "Deque after pop operations: ";


for (int x : dq)
cout << x << " ";
cout << endl;

// Insert and erase elements


dq.push_back(20);
dq.push_back(30);
dq.insert(dq.begin() + 1, 25);
16 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

cout << "Deque after insert: ";


for (int x : dq)
cout << x << " ";
cout << endl;

dq.erase(dq.begin());
cout << "Deque after erase: ";
for (int x : dq)
cout << x << " ";
cout << endl;

// Clear the deque


dq.clear();
cout << "Is deque empty? " << (dq.empty() ? "Yes" : "No") << endl;
return 0;
}
Output:
Deque after push operations: 5 10 15
Front element: 5
Back element: 15
Deque after pop operations: 10
Deque after insert: 10 25 20 30
Deque after erase: 25 20 30
Is deque empty? Yes
5. Stack

A stack is a container adapter designed to operate in LIFO (Last In, First Out) order, meaning
elements are added and removed only from one end, called the top of the stack.
Stacks internally use other standard containers like vector or deque for their implementation.

Key Functions of Stack:

1. empty(): Checks if the stack is empty.


17 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

2. size(): Returns the number of elements in the stack.

3. top(): Provides access to the topmost element of the stack.

4. push(g): Adds the element g to the top of the stack.

5. pop(): Removes the topmost element of the stack.

Features of Stack:

 Operates only at the top, making it highly efficient for operations like function calls,
undo mechanisms, etc.

 Ideal for solving problems such as expression evaluation, parenthesis balancing, and
DFS in graphs.

Example: Program to demonstrate functioning of stack container

#include <iostream>
#include <stack>
using namespace std;

int main() {
stack<int> s;

// Pushing elements into the stack


s.push(10);
s.push(20);
s.push(30);

cout << "Initial stack size: " << s.size() << endl;

// Accessing the top element


cout << "Top element: " << s.top() << endl;

// Removing the top element


s.pop();
18 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

cout << "After pop, new top element: " << s.top() << endl;

// Checking if the stack is empty


cout << "Is the stack empty? " << (s.empty() ? "Yes" : "No") <<
endl;

// Popping all elements


while (!s.empty()) {
cout << "Popped element: " << s.top() << endl;
s.pop();
}

cout << "Stack is now empty. Size: " << s.size() << endl;

return 0;
}
Output:
Initial stack size: 3
Top element: 30
After pop, new top element: 20
Is the stack empty? No
Popped element: 20
Popped element: 10
Stack is now empty. Size: 0
6. Set

Sets are associative containers that store unique elements in a specific order. They
automatically sort their elements using an internal sorting algorithm.

You can insert and remove values in the set, but all elements in a set are unique, meaning
duplicates are not allowed.

Basic Functions of Set:

1. begin(): Returns an iterator pointing to the first element in the set.


19 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

2. end(): Returns an iterator pointing to the theoretical element that follows the last
element in the set.

3. size(): Returns the number of elements currently stored in the set.

4. max_size(): Returns the maximum number of elements the set can hold (dependent
on system and implementation).

5. empty(): Returns whether the set is empty (true if empty, false otherwise).

6. insert(const g): Adds a new element g to the set. If g already exists, the insertion
is ignored.

7. lower_bound(const g): Returns an iterator pointing to the first element that is not
less than g, or the first element that is equivalent to g or greater.

8. upper_bound(const g): Returns an iterator pointing to the first element that is


greater than g, or the first element that is strictly greater than g.

Example: Program to demonstrate functioning of Set container

#include <iostream>
#include <set>
using namespace std;

int main() {
// Creating a set of integers
set<int> s;

// Inserting elements into the set


s.insert(10);
s.insert(20);
s.insert(15);
s.insert(5);
s.insert(25);
s.insert(10); // Duplicate value, will be ignored
20 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

// Displaying the elements of the set


cout << "Elements in the set: ";
for (auto it = s.begin(); it != s.end(); ++it) {
cout << *it << " ";
}
cout << endl;

// Checking if the set is empty


cout << "Is the set empty? " << (s.empty() ? "Yes" : "No") <<
endl;

// Finding the size of the set


cout << "Size of the set: " << s.size() << endl;

// Demonstrating lower_bound and upper_bound


int x = 15;
auto lb = s.lower_bound(x);
auto ub = s.upper_bound(x);

if (lb != s.end()) {
cout << "Lower bound of " << x << " is: " << *lb << endl;
} else {
cout << "Lower bound of " << x << " does not exist." << endl;
}

if (ub != s.end()) {
cout << "Upper bound of " << x << " is: " << *ub << endl;
} else {
cout << "Upper bound of " << x << " does not exist." << endl;
}

return 0;
21 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

}
Output:
Elements in the set: 5 10 15 20 25
Is the set empty? No
Size of the set: 5
Lower bound of 15 is: 15
Upper bound of 15 is: 20
7. Map

Maps are associative (ordered) containers that store key-value pairs, where each key is unique
and used to sort the elements in the container. The value is associated with its corresponding
key.

In a map, the keys are used to uniquely identify elements, and the values store the content
corresponding to those keys. Maps automatically sort elements by the key.

Example: In a map, a pair like "name" = "Rohan" represents a key-value pair, where
"name" is the key and "Rohan" is the value.

Methods of Map

1. begin(): Returns an iterator to the first element in the map.

2. end(): Returns an iterator to the theoretical element that follows the last element in the
map.

3. size(): Returns the number of elements in the map.

4. max_size(): Returns the maximum number of elements the map can hold.

5. empty(): Returns whether the map is empty. Returns true if the map is empty, false
otherwise.

6. insert(key, value): Adds a new element to the map with the specified key and value.
If the key already exists, it does not insert the duplicate key.

7. erase(iterator position): Removes the element at the position pointed to by the


iterator.

8. erase(const key): Removes the element associated with the specified key from the map.
22 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

9. clear(): Removes all elements from the map, leaving it empty.

Example: Program to demonstrate the use of the map container

#include <iostream>
#include <map>
using namespace std;

int main() {
// Create a map where key is a string and value is an integer
map<string, int> myMap;

// Inserting key-value pairs into the map


myMap["Alice"] = 30;
myMap["Bob"] = 25;
myMap["Charlie"] = 35;

// Displaying all elements using an iterator


cout << "Elements in the map:\n";
for (auto it = myMap.begin(); it != myMap.end(); ++it) {
cout << it->first << " : " << it->second << endl;
}

// Accessing a value using the key


cout << "\nAge of Bob: " << myMap["Bob"] << endl;

// Erasing an element by key


myMap.erase("Alice");

// Displaying elements after erasing "Alice"


cout << "\nElements after erasing 'Alice':\n";
for (auto it = myMap.begin(); it != myMap.end(); ++it) {
cout << it->first << " : " << it->second << endl;
23 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

// Checking if the map is empty


if (myMap.empty()) {
cout << "\nThe map is empty.\n";
} else {
cout << "\nThe map is not empty.\n";
}

// Displaying the size of the map


cout << "Size of the map: " << myMap.size() << endl;

return 0;
}
Output:
Elements in the map:
Alice : 30
Bob : 25
Charlie : 35

Age of Bob: 25

Elements after erasing 'Alice':


Bob : 25
Charlie : 35

The map is not empty.


Size of the map: 2

2. Algorithms
The Standard Template Library (STL) offers over 80 generic algorithms that can operate on
a wide variety of containers and ranges. These algorithms are stand-alone functions, not
24 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

member functions of container classes, which means they can operate on both C-style arrays
and STL containers. The <algorithm> header defines these algorithms, and they are designed
to be used with iterators to apply operations on container elements.

Non-Modifying Sequence Operations: These algorithms do not modify the container but
allow testing and searching operations:

1. std::all_of: Tests if all elements in a range satisfy a condition.

2. std::any_of: Tests if any element in the range satisfies a condition.

3. std::none_of: Tests if no element satisfies the condition.

4. std::for_each: Applies a function to each element in a range.

5. std::find: Finds the first occurrence of a value in a range.

6. std::find_if: Finds the first element satisfying a condition.

7. std::find_if_not: Finds the first element not satisfying a condition.

8. std::find_end: Finds the last occurrence of a subsequence in a range.

9. std::find_first_of: Finds the first element in a set from the range.

10. std::adjacent_find: Finds the first pair of adjacent equal elements.

11. std::count: Counts the occurrences of a value in a range.

12. std::count_if: Counts elements in a range satisfying a condition.

13. std::mismatch: Returns the first position where two ranges differ.

14. std::equal: Checks if two ranges have equal elements.

15. std::is_permutation: Tests if one range is a permutation of another.

16. std::search: Searches for a subsequence in a range.

17. std::search_n: Searches for an element in a range.

Modifying Sequence Operations: These algorithms modify the elements in the container

1. std::copy: Copies a range of elements.

2. std::copy_n: Copies a specific number of elements.


25 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

3. std::copy_if: Copies elements that satisfy a condition.

4. std::copy_backward: Copies a range of elements backward.

5. std::move: Moves a range of elements.

6. std::move_backward: Moves elements in reverse order.

7. std::swap: Swaps two values.

8. std::swap_ranges: Swaps two ranges of elements.

9. std::iter_swap: Swaps the values pointed to by two iterators.

10. std::transform: Applies a transformation to a range of elements.

11. std::replace: Replaces all occurrences of a value in a range.

12. std::replace_if: Replaces elements satisfying a condition.

13. std::replace_copy: Copies a range with replacements.

14. std::replace_copy_if: Copies a range with replacements based on a condition.

15. std::fill: Fills a range with a specific value.

16. std::fill_n: Fills a sequence with a specific value.

17. std::generate: Generates values for a range using a function.

18. std::generate_n: Generates values for a sequence using a function.

19. std::remove: Removes a value from a range.

20. std::remove_if: Removes elements satisfying a condition.

21. std::remove_copy: Copies a range while removing a value.

22. std::remove_copy_if: Copies a range while removing elements satisfying a


condition.

23. std::unique: Removes consecutive duplicates in a range.

24. std::unique_copy: Copies a range removing consecutive duplicates.

25. std::reverse: Reverses the order of elements in a range.


26 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

26. std::reverse_copy: Copies a range in reversed order.

27. std::rotate: Rotates the elements in a range to the left.

28. std::rotate_copy: Copies a rotated range of elements.

29. std::random_shuffle: Randomly shuffles elements in a range.

30. std::shuffle: Randomly shuffles elements using a random number generator.

Partition Operations: These algorithms partition ranges into groups based on a condition

1. std::is_partitioned: Tests if a range is partitioned.

2. std::partition: Partitions a range into two parts based on a condition.

3. std::stable_partition: Stable partitioning of a range.

4. std::partition_copy: Copies the partitioned range into two.

5. std::partition_point: Returns the point where a range is partitioned.

Sorting: These algorithms sort the elements of a range:

1. std::sort: Sorts elements in a range.

2. std::stable_sort: Sorts elements while maintaining the relative order of equal


elements.

3. std::partial_sort: Partially sorts a range.

4. std::partial_sort_copy: Copies and partially sorts a range.

5. std::is_sorted: Checks if a range is sorted.

6. std::is_sorted_until: Finds the first unsorted element in a range.

7. std::nth_element: Reorders the elements in a range such that the n-th element is in
its correct position.

Binary Search Operations (on sorted ranges): These algorithms perform binary search
operations:

1. std::lower_bound: Returns the iterator to the first element not less than the given
value.
27 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

2. std::upper_bound: Returns the iterator to the first element greater than the given
value.

3. std::equal_range: Returns a pair of iterators marking the range of elements


equivalent to a given value.

4. std::binary_search: Tests if a value exists in a sorted range.

Merge Operations (on sorted ranges): These algorithms are used to merge sorted ranges

1. std::merge: Merges two sorted ranges into a single sorted range.

2. std::inplace_merge: Merges consecutive sorted ranges into a single sorted range.

3. std::includes: Tests if one sorted range is a subset of another sorted range.

4. std::set_union: Computes the union of two sorted ranges.

5. std::set_intersection: Computes the intersection of two sorted ranges.

6. std::set_difference: Computes the difference of two sorted ranges.

7. std::set_symmetric_difference: Computes the symmetric difference of two


sorted ranges.

Heap Operations

These algorithms operate on heap structures:

1. std::push_heap: Pushes an element into the heap.

2. std::pop_heap: Pops an element from the heap.

3. std::make_heap: Converts a range into a heap.

4. std::sort_heap: Sorts elements of a heap.

5. std::is_heap: Tests if a range is a valid heap.

6. std::is_heap_until: Finds the first element not satisfying the heap property.

Min/Max Operations

These algorithms find the smallest or largest elements:

1. std::max: Returns the larger of two values.


28 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

2. std::minmax: Returns both the smallest and largest elements.

3. std::min_element: Finds the smallest element in a range.

4. std::max_element: Finds the largest element in a range.

5. std::minmax_element: Finds the smallest and largest elements in a range.

Other Operations

Additional useful algorithms:

1. std::lexicographical_compare: Compares two ranges lexicographically.

2. std::next_permutation: Transforms a range into the next permutation.

3. std::prev_permutation: Transforms a range into the previous permutation.

2.1 Sorting Algorithms

Sorting is one of the most fundamental operations on data, which arranges elements in a
particular order (typically increasing or decreasing). C++ provides a built-in sorting function
in the STL called sort(), which is highly efficient.

The sort() function internally uses IntroSort, a hybrid algorithm combining QuickSort,
HeapSort, and InsertionSort. By default, it uses QuickSort, but if QuickSort’s partitioning
becomes inefficient (e.g., it takes more than NlogN time), the algorithm switches to HeapSort.
For very small arrays, it switches to InsertionSort.

Prototype:

sort(startaddress, endaddress);

 startaddress: Address of the first element of the array.

 endaddress: Address of the next element after the last element.

The sort() function sorts the range [startaddress, endaddress).

Stable Sort

A stable sort ensures that the relative order of equal elements is preserved. The
stable_sort() function guarantees that if two elements are equivalent, their order in the
original container will be retained after sorting.
29 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

Prototype:

void stable_sort(range-begin, range-end);

void stable_sort(range-begin, range-end, binary-predicate-function);

 range-begin and range-end define the range to be sorted.

 binary-predicate-function is an optional argument that defines how to compare two


elements.

Example:

std::vector<std::string> vec = {"apple", "banana", "cherry", "apple"};

std::stable_sort(vec.begin(), vec.end(), [](const std::string& a, const


std::string& b) {

return a.size() < b.size();

});

In the above example, stable_sort() ensures that the relative order of equal-length strings
(like "apple") is preserved.

Partial Sort

The partial_sort() function is used when you want to sort only a portion of the data.
Unlike sort(), which sorts the entire range, partial_sort() sorts only the first part,
leaving the remaining elements in an unspecified order.

For example, if you want to find the smallest k elements in a container:

std::vector<int> vec = {12, 7, 9, 3, 5, 15, 8};

std::partial_sort(vec.begin(), vec.begin() + 3, vec.end());

Here, only the first three elements are sorted in ascending order, while the rest are left unsorted.

Heap Sort

The heap_sort() function is an STL algorithm used to sort elements in a heap range. It works
in ascending order and requires that the elements are arranged in a heap structure before sorting.

Two Versions:
30 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

1. Using default comparison (<):

void sort_heap(RandIter start, RandIter end);

 start and end are iterators marking the range to be sorted.

2. Using a custom comparison function:

void sort_heap(RandIter start, RandIter end, Comp cmpfn);

 cmpfn is a custom comparison function or function object that defines the sorting order.

The sort_heap() function does not return any value (it operates in place).

Example:

std::vector<int> vec = {10, 20, 5, 8};

std::make_heap(vec.begin(), vec.end()); // Make a heap

std::sort_heap(vec.begin(), vec.end()); // Sort the heap

Example: Program to demonstrate use of sorting algorithms

#include <iostream>
#include <vector>
#include <algorithm> // For std::sort

int main() {
// Initialize a vector of integers
std::vector<int> vec = {12, 7, 9, 3, 5, 15, 8};

// Display the vector before sorting


std::cout << "Before sorting: ";
for (int num : vec) {
std::cout << num << " ";
}
std::cout << std::endl;

// Sorting the vector using std::sort


31 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

std::sort(vec.begin(), vec.end());

// Display the vector after sorting


std::cout << "After sorting: ";
for (int num : vec) {
std::cout << num << " ";
}
std::cout << std::endl;

return 0;
}
2.2 Searching Algorithms

Efficient information retrieval is crucial as it saves time and ensures smooth execution of
subsequent tasks. Searching algorithms are designed to quickly locate a specific piece of
information within a dataset. Among these, Binary Search stands out as one of the most
efficient techniques.

Binary Search

Binary Search is a widely used algorithm for finding an element in a sorted array. It operates
using the divide-and-conquer approach, repeatedly halving the search space until the target is
found or the search space is exhausted.

How Binary Search Works:

1. Precondition: The array must be sorted before applying Binary Search.

2. Comparison: The middle element of the array is compared to the target value:

o If the middle element matches the target, the search is successful, and the index
of the middle element is returned.

o If the middle element is greater than the target, the search is confined to the left
sub-array.

o If the middle element is smaller than the target, the search continues in the right
sub-array.
32 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

3. The process repeats until the target is found or the array can no longer be divided.

Function Prototype:

binary_search(startaddress, endaddress, valuetofind)

 startaddress: The address of the first element in the array (or container).

 endaddress: The address of the next position after the last element in the array.

 valuetofind: The target value to be searched within the range.

Advantages of Binary Search:

 Time Efficiency: Operates in O(log N), making it much faster than linear search for
large datasets.

 Simplicity: Straightforward and easy to implement in sorted arrays or containers.

Limitations:

 The array must be sorted beforehand, which may add preprocessing overhead if the data
is unsorted.

 Not suitable for unsorted or dynamically changing data without frequent re-sorting.

Example:

#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

int main() {
vector<int> arr = {1, 3, 5, 7, 9, 11, 13};

// Search for the value 7 in the array


if (binary_search(arr.begin(), arr.end(), 7)) {
cout << "Element found!" << endl;
} else {
33 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

cout << "Element not found." << endl;


}

return 0;
}
2.3 min-max Algorithms

C++ has defined some functions to get smallest and largest elements among 2 or in a container
using different functions. But there are also functions that are used to get both smallest and
largest element using a single function, “minmax()” function achieves this task for use. This
function is defined in “algorithm” header file.

1. minmax(a, b): This function returns a pair, in which 1st element is of minimum of the two
elements and the 2nd element is maximum of 2 elements.

2. minmax(array of elements): This function returns similarly as first version. Only


difference is that in this version, the accepted argument is a list of integers/strings among which
maximum and minimum are obtained. Useful in cases when we need to find maximum and
minimum elements in list without sorting.

Example:

#include <iostream>
#include <algorithm> // For minmax
#include <vector>

using namespace std;

int main() {
// Example array
vector<int> arr = {42, 15, 78, 4, 56, 19};

// Using minmax_element
auto result = minmax_element(arr.begin(), arr.end());
34 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

// Displaying the results


cout << "Array: ";
for (int num : arr) {
cout << num << " ";
}
cout << endl;

cout << "Minimum value: " << *result.first << endl;


cout << "Maximum value: " << *result.second << endl;

return 0;
}
Output:
Array: 42 15 78 4 56 19
Minimum value: 4
Maximum value: 78

3. Iterators

Iterators are objects that act as pointers to elements within STL containers, allowing access and
traversal of data. They enable cycling through container elements efficiently, reducing
complexity and execution time in programs. Iterators are versatile and can be incremented or
decremented to move through a container's elements.

Operations of Iterators

1. begin(): Returns an iterator pointing to the beginning of the container.

2. end(): Returns an iterator pointing to the position after the last element of the
container.

3. advance(): Moves an iterator forward by a specified number of positions.

4. next(): Returns a new iterator advanced by the specified number of positions.

5. prev(): Returns a new iterator decremented by the specified number of positions.


35 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

6. inserter(): Inserts elements at a specific position in a container. Accepts the


container and the iterator pointing to the position as arguments.

Types of Iterators

1. Input Iterator:

o Used for accessing elements without modifying them (read-only).

o Operators: ++, ==, !=, *

2. Output Iterator:

o Used for modifying elements without reading them (write-only).

o Operators: ++, =

3. Forward Iterator:

o Allows reading and writing to a container in a single forward pass.

o Operators: ++, =, ==, !=

4. Bidirectional Iterator:

o Adds backward traversal (decrement --) to the features of a forward iterator.

o Operators: ++, --, =, ==, !=

5. Random Access Iterator:

o Supports all bidirectional iterator features and allows direct access to elements
using addition (+) or subtraction (-).

o Operators: ++, --, +, -, [], ==, !=, <, >, <=, >=

Iterator Characteristics

Iterator Type Access Method Direction of Movement Capabilities


Input Linear Forward only Read-only
Output Linear Forward only Write-only
Forward Linear Forward only Read/Write
Bidirectional Linear Forward & backward Read/Write
Random Random Forward & backward Read/Write + Random Access
36 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

Providers of Iterators

 Input Iterator: istream

 Output Iterator: ostream

 Forward Iterator: Most STL containers

 Bidirectional Iterator: list, set, multiset, map, multimap

 Random Access Iterator: vector, deque, array

Advantages of Iterators

1. Ease of Programming: Using iterators is simpler than the subscript operator ([]) as
they eliminate the need to track element counts.

2. Code Reusability: Iterators enable reusability; for example, they work with both vector
and list, unlike the subscript operator.

3. Dynamic Processing: Iterators facilitate dynamic addition and deletion of data within
containers.

Disadvantages of Iterators

1. Limited Multitasking: Iterators cannot switch between multiple data structures


simultaneously.

2. Structural Restrictions: Modifying a container during iteration can invalidate iterators


and disrupt processing.

3. No Backtracking: Input and output iterators do not support backtracking during


traversal.

Example:

#include <iostream>
#include <vector>
#include <list>
#include <iterator> // For advance, next, prev, and inserter

using namespace std;


37 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

int main() {
// Example with vector
vector<int> vec = {10, 20, 30, 40, 50};
cout << "Vector elements using iterators: ";
for (vector<int>::iterator it = vec.begin(); it != vec.end();
++it) {
cout << *it << " ";
}
cout << endl;

// Example with list


list<int> lst = {100, 200, 300, 400, 500};
list<int>::iterator it = lst.begin();

// Using advance
advance(it, 2); // Move iterator to the 3rd position
cout << "Using advance to move to 3rd element in list: " << *it
<< endl;

// Using next and prev


list<int>::iterator next_it = next(it, 1); // Move 1 step forward
list<int>::iterator prev_it = prev(it, 1); // Move 1 step backward
cout << "Next element: " << *next_it << ", Previous element: " <<
*prev_it << endl;

// Using inserter to add elements to vector


vector<int> newVec = {60, 70, 80};
inserter(vec, vec.end()) = 90; // Insert 90 at the end
cout << "Vector after using inserter: ";
for (int v : vec) {
cout << v << " ";
}
38 | P a g e © Haris Chaus | ALL RIGHTS ARE RESERVED as per copyright act.

cout << endl;


return 0;
}
Output:
Vector elements using iterators: 10 20 30 40 50
Using advance to move to 3rd element in list: 300
Next element: 400, Previous element: 200
Vector after using inserter: 10 20 30 40 50 90

Difference between Iterators and Pointers

Aspect Iterators Pointers


Definition Generalized objects used to Variables that store the memory address
traverse container elements. of another variable.
Use Designed for STL containers (e.g., Used for direct memory access and
vector, list). manipulation.
Behavior Supports navigation with Similar navigation but operates directly
operations like ++, --. on memory addresses.
Bounds Works within container No bounds checking, prone to undefined
Checking boundaries (logical abstraction). behavior if misused.
Flexibility Abstracted and safer for container Low-level and unrestricted, suitable for
traversal. any memory location.
Container Specific to STL containers and Independent of containers and can be
Dependency their traversal. used anywhere.
Error-Prone Safer due to integration with STL More prone to errors like segmentation
container logic. faults or memory leaks.
Overhead Slight overhead due to abstraction Minimal overhead as pointers work
in STL containers. directly with memory.

You might also like