In C++, the standard template library (STL) provides a powerful collection of underlying functions under the <algorithm> header. These functions help in a wide range of operations on sequences, such as arrays , vectors , lists , and other containers. Algorithm functions are general-purpose and operate on iterators, which makes them reusable across several container types.
Types of Algorithm
There are mainly two types of algorithms. These are as follows:
- Non-mutating Algorithms
- Mutating Algorithms
Now, we will discuss these algorithms one by one.
Non-Mutating Algorithms
In C++ , non-mutating algorithms operate on a sequence of elements without changing their values. Their major use is to execute queries, comparisons, and inspections across a variety of elements. These algorithms work well when the purpose is to retrieve information rather than change the contents of a container. Common examples include find, which looks for a given value, and count, which counts the number of times a particular element appears.
These functions are efficient, ensure data integrity, and are critical tools for analyzing or verifying elements in STL containers, such as vectors, lists, and arrays.
Mutating Algorithms
In C++, mutating algorithms are those algorithms that update or rearrange the elements in a range. These algorithms alter the original instead of creating a new container. There are several mutating algorithms, such as sort, reverse, rotate, partition, remove, etc. These algorithms are commonly utilized for efficient in-place data transformations.
Member Functions of C++ Algorithm
Below is the list of all member functions of the map:
Standard Non-Modifying Sequence Algorithms
The given table shows several standard non-modifying sequence operations that are used in C++ Algorithms.
| Function | Description |
|---|---|
| all_of | This function is used to tests a condition to all the elements of the range. |
| any_of | This function is used to tests a condition to some or any of the elements of the range |
| none_of | This function is used to checks if none of the elements follow the condition or not. |
| for_each | The function applies an operation to all the elements of the range. |
find |
The function finds a value in the range. |
| find_if | The function finds for an element in the range. |
| findifnot | The function finds an element in the range but in the opposite way as the above one. |
| find_end | The function is used to return the last element of the range. |
| findfirstof | The function finds for the element that satisfies a condition and occurs at the first. |
| adjacent_find | The function makes a search for finding the equal and adjacent elements in a range. |
| count | The function returns the count of a value in the range. |
| count_if | The function returns the count of values that satisfy a condition. |
| mismatch | The function returns the value in sequence which is the first mismatch. |
| equal | The function is used to check if the two ranges have all elements equal. |
| is_permutation | The function checks whether the range in reference is a permutation of some other range. |
| search | The function searches for the subsequence in a range. |
| search_n | The function searches the range for the occurrence of an element. |
C++ Non-Modifying Sequence Operations Example
Let us take an example to illustrate the non-modifying sequence operations in C++.
Example
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric> // for iota function
using namespace std; //using standard namespace
int main() { //main function
vector<int> data = {2, 4, 6, 8, 10, 3, 4, 6, 8, 10};
// all_of
bool allEven = all_of(data.begin(), data.end(), [](int x){ return x % 2 == 0; });
cout << "All elements are even? " << boolalpha << allEven << endl;
// any_of
bool anyOdd = any_of(data.begin(), data.end(), [](int x){ return x % 2 != 0; });
cout << "Any element is odd? " << boolalpha << anyOdd << endl;
// none_of
bool noneNegative = none_of(data.begin(), data.end(), [](int x){ return x < 0; });
cout << "No negative elements? " << boolalpha << noneNegative << endl;
// for_each
cout << "Elements: ";
for_each(data.begin(), data.end(), [](int x){ cout << x << " "; });
cout << endl;
// find
auto it1 = find(data.begin(), data.end(), 6);
if (it1 != data.end())
cout << "First occurrence of 6 found at index: " << distance(data.begin(), it1) << endl;
// find_if
auto it2 = find_if(data.begin(), data.end(), [](int x){ return x > 8; });
if (it2 != data.end())
cout << "First element > 8 is: " << *it2 << endl;
// find_if_not
auto it3 = find_if_not(data.begin(), data.end(), [](int x){ return x % 2 == 0; });
if (it3 != data.end())
cout << "First non-even element: " << *it3 << endl;
// find_end
vector<int> sub1 = {4, 6};
auto it4 = find_end(data.begin(), data.end(), sub1.begin(), sub1.end());
if (it4 != data.end())
cout << "Last occurrence of {4, 6} starts at index: " << distance(data.begin(), it4) << endl;
// find_first_of
vector<int> targets = {3, 7, 9};
auto it5 = find_first_of(data.begin(), data.end(), targets.begin(), targets.end());
if (it5 != data.end())
cout << "First matching element from {3,7,9} is: " << *it5 << endl;
// adjacent_find
vector<int> repeated = {1, 2, 3, 3, 4, 5};
auto it6 = adjacent_find(repeated.begin(), repeated.end());
if (it6 != repeated.end())
cout << "First pair of adjacent equal elements: " << *it6 << " and " << *(it6 + 1) << endl;
// count
int count_4 = count(data.begin(), data.end(), 4);
cout << "Count of 4s in data: " << count_4 << endl;
// count_if
int count_gt_5 = count_if(data.begin(), data.end(), [](int x){ return x > 5; });
cout << "Count of elements > 5: " << count_gt_5 << endl;
// mismatch
vector<int> d1 = {1, 2, 3, 4, 5};
vector<int> d2 = {1, 2, 0, 4, 5};
auto [m1, m2] = mismatch(d1.begin(), d1.end(), d2.begin());
cout << "First mismatch: " << *m1 << " vs " << *m2 << endl;
// equal
bool areEqual = equal(d1.begin(), d1.end(), d2.begin());
cout << "Are d1 and d2 equal? " << boolalpha << areEqual << endl;
// is_permutation
vector<int> a = {1, 2, 3};
vector<int> b = {3, 2, 1};
bool isPerm = is_permutation(a.begin(), a.end(), b.begin());
cout << "Is b a permutation of a? " << boolalpha << isPerm << endl;
// search
vector<int> needle = {6, 8};
auto it7 = search(data.begin(), data.end(), needle.begin(), needle.end());
if (it7 != data.end())
cout << "Subsequence {6,8} found at index: " << distance(data.begin(), it7) << endl;
// search_n
auto it8 = search_n(data.begin(), data.end(), 2, 4);
if (it8 != data.end())
cout << "Two consecutive 4s found at index: " << distance(data.begin(), it8) << endl;
return 0;
}
Output:
All elements are even? false
Any element is odd? true
No negative elements? true
Elements: 2 4 6 8 10 3 4 6 8 10
First occurrence of 6 found at index: 2
First element > 8 is: 10
First non-even element: 3
Last occurrence of {4, 6} starts at index: 6
First matching element from {3,7,9} is: 3
First pair of adjacent equal elements: 3 and 3
Count of 4s in data: 2
Count of elements > 5: 6
First mismatch: 3 vs 0
Are d1 and d2 equal? false
Is b a permutation of a? true
Subsequence {6,8} found at index: 2
Modifying Sequence Operations
The given table shows several modifying sequence operations that are used in C++ Algorithm.
| Function | Description |
|---|---|
copy |
The function copies the range of elements. |
| copy_n | The function copies n elements of the range |
| copy_if | The function copies the elements of the range if a certain condition is fulfilled. |
| copy_backward | The function copies the elements in a backward order |
move |
The function moves the ranges of elements. |
| move_backward | The function moves the range of elements in the backward order |
swap |
The function swaps the value of two objects. |
| swap_ranges | The function swaps the value of two ranges. |
| iter_swap | The function swaps the values of two iterators under reference. |
| transform | The function transforms all the values in a range. |
| replace | The function replaces the values in the range with a specific value. |
| replace_if | The function replaces the value of the range if a certain condition is fulfilled. |
| replace_copy | The function copies the range of values by replacing with an element. |
| replacecopyif | The function copies the range of values by replacing with an element if a certain condition is fulfilled. |
fill |
The function fills the values in the range with a value. |
| fill_n | The function fills the values in the sequence. |
| generate | The function is used for the generation of values of the range. |
| generate_n | The function is used for the generation of values of the sequence. |
| remove | The function removes the values from the range. |
| remove_if | The function removes the values of the range if a condition is fulfilled. |
| remove_copy | The function copies the values of the range by removing them. |
| removecopyif | The function copies the values of the range by removing them if a condition is fulfilled. |
| unique | The function identifies the unique element of the range. |
| unique_copy | The function copies the unique elements of the range. |
| reverse | The function reverses the range. |
| reverse_copy | The function copies the range by reversing values. |
| rotate | The function rotates the elements of the range in left direction. |
| rotate_copy | The function copies the elements of the range which is rotated left. |
| random_shuffle | The function shuffles the range randomly. |
| shuffle | The function shuffles the range randomly with the help of a generator. |
C++ Modifying Sequence Operations Example
Let us take an example to demonstrate the modifying sequence operations in C++.
Example
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric> // For iota
#include <random> // For shuffle
using namespace std; //using standard namespace
int main() { //main function
vector<int> original(10);
iota(original.begin(), original.end(), 1); // Fill with 1 to 10
// copy
vector<int> copied(10);
copy(original.begin(), original.end(), copied.begin());
cout << "Copied vector: ";
for (int x : copied) cout << x << " ";
cout << endl;
// copy_if (copy only even numbers)
vector<int> evens;
copy_if(original.begin(), original.end(), back_inserter(evens), [](int x) { return x % 2 == 0; });
cout << "Even elements (copy_if): ";
for (int x : evens) cout << x << " ";
cout << endl;
// transform (multiply each element by 2)
vector<int> doubled(10);
transform(original.begin(), original.end(), doubled.begin(), [](int x) { return x * 2; });
cout << "Transformed (doubled) vector: ";
for (int x : doubled) cout << x << " ";
cout << endl;
// replace (replace 5 with 99)
vector<int> replaced = original;
replace(replaced.begin(), replaced.end(), 5, 99);
cout << "Replaced 5 with 99: ";
for (int x : replaced) cout << x << " ";
cout << endl;
// remove (remove value 3)
vector<int> removed = original;
auto new_end = remove(removed.begin(), removed.end(), 3);
removed.erase(new_end, removed.end()); // Physically erase
cout << "Removed 3 from vector: ";
for (int x : removed) cout << x << " ";
cout << endl;
// unique (remove adjacent duplicates)
vector<int> with_dupes = {1, 1, 2, 2, 2, 3, 3, 4};
auto last_unique = unique(with_dupes.begin(), with_dupes.end());
with_dupes.erase(last_unique, with_dupes.end());
cout << "After unique(): ";
for (int x : with_dupes) cout << x << " ";
cout << endl;
// reverse
vector<int> reversed = original;
reverse(reversed.begin(), reversed.end());
cout << "Reversed vector: ";
for (int x : reversed) cout << x << " ";
cout << endl;
// rotate (move first 3 elements to end)
vector<int> rotated = original;
rotate(rotated.begin(), rotated.begin() + 3, rotated.end());
cout << "Rotated vector (left by 3): ";
for (int x : rotated) cout << x << " ";
cout << endl;
// swap_ranges (swap original with doubled)
vector<int> swapped1 = original, swapped2 = doubled;
swap_ranges(swapped1.begin(), swapped1.end(), swapped2.begin());
cout << "After swap_ranges(), swapped1: ";
for (int x : swapped1) cout << x << " ";
cout << "\nAfter swap_ranges(), swapped2: ";
for (int x : swapped2) cout << x << " ";
cout << endl;
// shuffle (modern C++11 shuffle)
vector<int> shuffled = original;
random_device rd;
mt19937 g(rd());
shuffle(shuffled.begin(), shuffled.end(), g);
cout << "Shuffled vector: ";
for (int x : shuffled) cout << x << " ";
cout << endl;
return 0;
}
Output:
Copied vector: 1 2 3 4 5 6 7 8 9 10
Even elements (copy_if): 2 4 6 8 10
Transformed (doubled) vector: 2 4 6 8 10 12 14 16 18 20
Replaced 5 with 99: 1 2 3 4 99 6 7 8 9 10
Removed 3 from vector: 1 2 4 5 6 7 8 9 10
After unique(): 1 2 3 4
Reversed vector: 10 9 8 7 6 5 4 3 2 1
Rotated vector (left by 3): 4 5 6 7 8 9 10 1 2 3
After swap_ranges(), swapped1: 2 4 6 8 10 12 14 16 18 20
After swap_ranges(), swapped2: 1 2 3 4 5 6 7 8 9 10
Shuffled vector: 6 9 1 7 4 3 5 8 2 10
Partitions
The given table shows several partition operations that are used in C++ Algorithm.
| Function | Description |
|---|---|
| is_partitioned | The function is used to deduce whether the range is partitioned or not. |
| partition | The function is used to partition the range. |
| stable_partition | The function partitions the range in two stable halves. |
| partition_copy | The function copies the range after partition. |
| partition_point | The function returns the partition point for a range. |
C++ Partition Operations Example
Let us take an example to demonstrate the partition operations in C++.
Example
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std; //using standard namespace
bool isEven(int x) {
return x % 2 == 0;
}
int main() { //main function
vector<int> data = {1, 2, 3, 4, 5, 6, 7, 8};
// Check if already partitioned
bool alreadyPartitioned = is_partitioned(data.begin(), data.end(), isEven);
cout << "Is the data partitioned (evens first)? " << boolalpha << alreadyPartitioned << endl;
// Apply partition (non-stable)
partition(data.begin(), data.end(), isEven);
cout << "After partition (evens first): ";
for (int x : data) cout << x << " ";
cout << endl;
// Apply stable_partition
vector<int> data2 = {1, 2, 3, 4, 5, 6, 7, 8};
stable_partition(data2.begin(), data2.end(), isEven);
cout << "After stable_partition (evens first, order preserved): ";
for (int x : data2) cout << x << " ";
cout << endl;
// Use partition_copy
vector<int> evens, odds;
evens.resize(data.size());
odds.resize(data.size());
auto result = partition_copy(data.begin(), data.end(),
evens.begin(), odds.begin(), isEven);
evens.resize(distance(evens.begin(), result.first));
odds.resize(distance(odds.begin(), result.second));
cout << "Partitioned copy - evens: ";
for (int x : evens) cout << x << " ";
cout << "\nPartitioned copy - odds: ";
for (int x : odds) cout << x << " ";
cout << endl;
// Use partition_point
auto it = partition_point(data.begin(), data.end(), isEven);
cout << "Partition point index: " << distance(data.begin(), it) << endl;
return 0;
}
Output:
Is the data partitioned (evens first)? false
After partition (evens first): 8 2 6 4 5 3 7 1
After stable_partition (evens first, order preserved): 2 4 6 8 1 3 5 7
Partitioned copy - evens: 8 2 6 4
Partitioned copy - odds: 5 3 7 1
Partition point index: 4
Sorting
The given table shows several sorting operations that are used in the C++ Algorithm.
| Function | Description |
|---|---|
sort |
The function sorts all the elements in a range. |
| stable_sort | The function sorts the elements in the range, maintaining the relative equivalent order. |
| partial_sort | The function partially sorts the elements of the range. |
| partialsortcopy | The function copies the elements of the range after sorting it. |
| is_sorted | The function checks whether the range is sorted or not. |
| issorteduntil | The function checks till which element a range is sorted. |
| nth_element | The functions sorts the elements in the range. |
C++ Sorting Operations Example
Let us take an example to demonstrate the sorting functions in C++.
Example
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std; //using standard namespace
void printVector(const vector<int>& v, const string& msg) {
cout << msg;
for (int x : v) cout << x << " ";
cout << endl;
}
int main() { //main function
vector<int> data = {7, 2, 9, 4, 3, 8, 1, 6, 5};
// 1. sort
vector<int> sorted = data;
sort(sorted.begin(), sorted.end());
printVector(sorted, "Sorted vector: ");
// 2. stable_sort
vector<pair<int, char>> stableData = {{3, 'a'}, {1, 'b'}, {3, 'c'}, {2, 'd'}};
stable_sort(stableData.begin(), stableData.end());
cout << "Stable sorted vector of pairs: ";
for (auto& p : stableData) cout << "(" << p.first << "," << p.second << ") ";
cout << endl;
// 3. partial_sort (smallest 5 elements)
vector<int> partial = data;
partial_sort(partial.begin(), partial.begin() + 5, partial.end());
printVector(partial, "Partially sorted (first 5 smallest): ");
// 4. partial_sort_copy
vector<int> dest(5);
partial_sort_copy(data.begin(), data.end(), dest.begin(), dest.end());
printVector(dest, "Partial sort copy (5 smallest): ");
// 5. is_sorted
bool sortedStatus = is_sorted(sorted.begin(), sorted.end());
cout << "Is the sorted vector actually sorted? " << boolalpha << sortedStatus << endl;
// 6. is_sorted_until
vector<int> partlySorted = {1, 2, 3, 7, 5, 6};
auto until = is_sorted_until(partlySorted.begin(), partlySorted.end());
cout << "is_sorted_until found unsorted at position: "
<< distance(partlySorted.begin(), until) << endl;
// 7. nth_element (place the 5th smallest element in correct position)
vector<int> nth = data;
nth_element(nth.begin(), nth.begin() + 4, nth.end()); // 5th smallest
printVector(nth, "After nth_element (5th smallest in correct place): ");
cout << "5th smallest element is: " << nth[4] << endl;
return 0;
}
Output:
Sorted vector: 1 2 3 4 5 6 7 8 9
Stable sorted vector of pairs: (1,b) (2,d) (3,a) (3,c)
Partially sorted (first 5 smallest): 1 2 3 4 5 9 8 7 6
Partial sort copy (5 smallest): 1 2 3 4 5
Is the sorted vector actually sorted? true
is_sorted_until found unsorted at position: 4
After nth_element (5th smallest in correct place): 3 2 1 4 5 7 6 9 8
5th smallest element is: 5
Binary Search
The given table shows several binary search operations that are used in C++ Algorithm.
| Function | Description |
|---|---|
| lower_bound | Returns the lower bound element of the range. |
| upper_bound | Returns the upper bound element of the range. |
| equal_range | The function returns the subrange for the equal elements. |
| binary_search | The function tests if the values in the range exist in a sorted sequence or not. |
C++ Binary Search Operations Example
Let us take an example to demonstrate the binary search operations in C++.
Example
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std; //using standard namespace
int main() { //main function
vector<int> data = {1, 3, 3, 3, 5, 7, 9, 11};
// Must be sorted before using binary search algorithms
cout << "Sorted data: ";
for (int x : data) cout << x << " ";
cout << endl;
int value = 3;
// 1. binary_search
bool found = binary_search(data.begin(), data.end(), value);
cout << "Is value " << value << " present? " << boolalpha << found << endl;
// 2. lower_bound
auto lower = lower_bound(data.begin(), data.end(), value);
cout << "Lower bound of " << value << " is at index: " << distance(data.begin(), lower)
<< ", value: " << *lower << endl;
// 3. upper_bound
auto upper = upper_bound(data.begin(), data.end(), value);
cout << "Upper bound of " << value << " is at index: " << distance(data.begin(), upper)
<< ", value: " << *upper << endl;
// 4. equal_range
auto range = equal_range(data.begin(), data.end(), value);
cout << "Equal range of " << value << " is from index "
<< distance(data.begin(), range.first) << " to "
<< distance(data.begin(), range.second) << endl;
cout << "Elements in equal range: ";
for (auto it = range.first; it != range.second; ++it)
cout << *it << " ";
cout << endl;
return 0;
}
Output:
Sorted data: 1 3 3 3 5 7 9 11
Is value 3 present? true
Lower bound of 3 is at index: 1, value: 3
Upper bound of 3 is at index: 4, value: 5
Equal range of 3 is from index 1 to 4
Elements in equal range: 3 3 3
Merge
The given table shows several merge operations that are used in C++ Algorithm.
Merge
| Function | Description |
|---|---|
| merge | The function merges two ranges that are in a sorted order. |
| inplace_merge | The function merges two consecutive ranges that are sorted. |
| includes | The function searches whether the sorted range includes another range or not. |
| set_union | The function returns the union of two ranges that are sorted. |
| set_intersection | The function returns the intersection of two ranges that are sorted. |
| set_difference | The function returns the difference of two ranges that are sorted. |
| setsymmetricdifference | The function returns the symmetric difference of two ranges that are sorted. |
C++ Merge Operations Example
Let us take an example to demonstrate the merge operations in C++.
Example
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std; //using standard namespace
void printVector(const vector<int>& v, const string& msg) {
cout << msg;
for (int x : v) cout << x << " ";
cout << endl;
}
int main() { //main function
vector<int> A = {1, 3, 5, 7};
vector<int> B = {2, 3, 6, 8};
// 1. merge
vector<int> merged(A.size() + B.size());
merge(A.begin(), A.end(), B.begin(), B.end(), merged.begin());
printVector(merged, "Merged A and B: ");
// 2. inplace_merge
vector<int> C = {1, 3, 5, 7, 2, 4, 6};
inplace_merge(C.begin(), C.begin() + 4, C.end());
printVector(C, "After inplace_merge: ");
// 3. includes
vector<int> superset = {1, 2, 3, 4, 5};
vector<int> subset = {2, 4};
bool result = includes(superset.begin(), superset.end(), subset.begin(), subset.end());
cout << "Does superset include subset? " << boolalpha << result << endl;
// 4. set_union
vector<int> unionResult(A.size() + B.size());
auto it1 = set_union(A.begin(), A.end(), B.begin(), B.end(), unionResult.begin());
unionResult.resize(it1 - unionResult.begin());
printVector(unionResult, "Set union: ");
// 5. set_intersection
vector<int> intersectionResult(min(A.size(), B.size()));
auto it2 = set_intersection(A.begin(), A.end(), B.begin(), B.end(), intersectionResult.begin());
intersectionResult.resize(it2 - intersectionResult.begin());
printVector(intersectionResult, "Set intersection: ");
// 6. set_difference (A - B)
vector<int> differenceResult(A.size());
auto it3 = set_difference(A.begin(), A.end(), B.begin(), B.end(), differenceResult.begin());
differenceResult.resize(it3 - differenceResult.begin());
printVector(differenceResult, "Set difference (A - B): ");
// 7. set_symmetric_difference
vector<int> symmetricDiffResult(A.size() + B.size());
auto it4 = set_symmetric_difference(A.begin(), A.end(), B.begin(), B.end(), symmetricDiffResult.begin());
symmetricDiffResult.resize(it4 - symmetricDiffResult.begin());
printVector(symmetricDiffResult, "Set symmetric difference: ");
return 0;
}
Output:
Merged A and B: 1 2 3 3 5 6 7 8
After inplace_merge: 1 2 3 4 5 6 7
Does superset include subset? true
Set union: 1 2 3 5 6 7 8
Set intersection: 3
Set difference (A - B): 1 5 7
Set symmetric difference: 1 2 5 6 7 8
The given table shows several heap operations that are used in the C++ Algorithm.
| Function | Description |
|---|---|
| push_heap | The function pushes new elements in the heap. |
| pop_heap | The function pops new elements in the heap. |
| make_heap | The function is used for the creation of a heap. |
| sort_heap | The function sorts the heap. |
| is_heap | The function checks whether the range is a heap. |
| isheapuntil | The function checks till which position a range is a heap. |
C++ Heap Operations Example
Let us take an example to demonstrate the heap operations in C++.
Example
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std; //using standard namespace
void printVector(const vector<int>& v, const string& msg) {
cout << msg;
for (int x : v) cout << x << " ";
cout << endl;
}
int main() { //main function
vector<int> heap = {10, 20, 30, 5, 15};
// 1. make_heap
make_heap(heap.begin(), heap.end());
printVector(heap, "Heap after make_heap: "); // Heapify the vector
// 2. push_heap (insert new element into heap)
heap.push_back(25); // Add new element at the end
push_heap(heap.begin(), heap.end());
printVector(heap, "Heap after push_heap(25): ");
// 3. pop_heap (remove root of heap)
pop_heap(heap.begin(), heap.end()); // Moves the largest to the end
cout << "Popped element: " << heap.back() << endl;
heap.pop_back(); // Actually remove the last element
printVector(heap, "Heap after pop_heap: ");
// 4. is_heap
bool result = is_heap(heap.begin(), heap.end());
cout << "Is the vector a heap? " << boolalpha << result << endl;
// 5. is_heap_until
vector<int> testHeap = {30, 20, 25, 10, 15, 5, 40}; // not a valid heap
auto it = is_heap_until(testHeap.begin(), testHeap.end());
cout << "is_heap_until fails at index: " << distance(testHeap.begin(), it) << endl;
// 6. sort_heap (converts heap into sorted array)
sort_heap(heap.begin(), heap.end());
printVector(heap, "Heap after sort_heap (sorted array): ");
return 0;
}
Output:
Heap after make_heap: 30 20 10 5 15
Heap after push_heap(25): 30 20 25 5 15 10
Popped element: 30
Heap after pop_heap: 25 20 10 5 15
Is the vector a heap? true
is_heap_until fails at index: 6
Heap after sort_heap (sorted array): 5 10 15 20 25
Min/Max
The given table shows several min/max operations that are used in C++ Algorithm.
| Function | Description |
|---|---|
min |
Returns the smallest element of the range. |
max |
Returns the largest element of the range. |
| minmax | Returns the smallest and largest element of the range. |
| min_element | Returns the smallest element of the range. |
| max_element | Returns the largest element of the range. |
| minmax_element | Returns the smallest and largest element of the range. |
C++ Min/Max Operations Example
Let us take an example to demonstrate the min/max operations in C++.
Example
#include <iostream>
#include <vector>
#include <algorithm>
#include <utility> // for std::pair
using namespace std; //using standard namespace
int main() { //main function
vector<int> nums = {12, 45, 23, 67, 34, 89, 11, 9};
// 1. min (between two values)
int a = 10, b = 20;
cout << "min(10, 20): " << min(a, b) << endl;
// 2. max (between two values)
cout << "max(10, 20): " << max(a, b) << endl;
// 3. minmax (between two values)
auto minmaxVal = minmax(a, b);
cout << "minmax(10, 20): (" << minmaxVal.first << ", " << minmaxVal.second << ")" << endl;
// 4. min_element (smallest element in the vector)
auto minIt = min_element(nums.begin(), nums.end());
cout << "Minimum element in vector: " << *minIt << " at index " << distance(nums.begin(), minIt) << endl;
// 5. max_element (largest element in the vector)
auto maxIt = max_element(nums.begin(), nums.end());
cout << "Maximum element in vector: " << *maxIt << " at index " << distance(nums.begin(), maxIt) << endl;
// 6. minmax_element (returns both min and max from range)
auto minmaxIt = minmax_element(nums.begin(), nums.end());
cout << "Minmax in vector: min = " << *minmaxIt.first << ", max = " << *minmaxIt.second << endl;
return 0;
}
Output:
min(10, 20): 10
max(10, 20): 20
minmax(10, 20): (10, 20)
Minimum element in vector: 9 at index 7
Maximum element in vector: 89 at index 5
Minmax in vector: min = 9, max = 89
Other Functions
The given table shows several other operations that are useful in C++ Algorithm.
| Function | Description |
|---|---|
| lexicographical_comapre | The function performs the lexicographical less-than comparison. |
| next_permutation | The function is used for the transformation of the range into the next permutation. |
| perv_permutation | The function is used for the transformation of the range into the previous permutation. |
Key features of C++ Algorithm Functions
There are several key features of C++ algorithm functions. Some main features are as follows:
- Generic and template-based: C++ algorithm functions are template-based, which allows them to work without re-writing with various data types and container types (such as vector, list, and array).
- Modifying and Non-Modifying Categories: The algorithm is grouped into non-modifying (such as find, count, and for_each) and modified (such as copy, replace, and transform) whether they change input data.
- Custom condition support: Many specific terms (eg, findif, countif) to define predicate functions or Lambdas, increase custom logic.
- Efficient and optimized: STL algorithms are adapted for performance and usually provide guaranteed time complexity (such as sort uses a hybrid sorting algorithm with complexity O(n log n).
- Do not resize containers: Algorithm containers do not manage size or memory.
Conclusion
In conclusion, the C++ algorithm function is an essential toolset for efficient and expressive programming, provided through the header in the standard template library (STL). They abstract low-level iteration logic and provide clean, customized operations for tasks such as searching, sorting, modifying, comparing, and transforming data.
C++ Algorithm FAQs
1) What is the purpose of the <algorithm> header in C++?
In C++, the <algorithm> header provides a wide collection of predetermined functions for operations, such as sorting, searching, counting, and modifying. This function simplifies the code by replacing the codes with the reusable logic. They work generously with containers using iterators. It promotes readability, efficiency, and abstraction in C++ programming.
2) Do C++ algorithm functions work with all types of containers?
Yes, algorithm functions operate on the iterators, not directly on containers, so they can be used with any STL container that supports iterators, such as vectors, lists, and even raw arrays. It makes the tasks highly flexible. The only limit is that some algorithm requires specific iterator types (e.g., sort needs random-access iterators).
3) What is the difference between std::sort and std::stable_sort?
In C++, the std::sort functions keep rapid and rearranged elements in order but do not preserve the original order of similar elements. On the other hand, the std::stableSort holds the same elements in its original relative positions, which makes the order suitable when it means. While the sort is more efficient, the stablesort ensures stability in multi-level pruning scenarios.
4) How does the algorithm function support the custom logic through predicates or lambdas?
Many algorithms accept a custom position, called a predicate, which can be a function pointer, functor, or lambda. It allows the function to apply user-defined arguments during operations, such as filtering, sorting, and searching. Lambdas is widely used to write compact and inline logic. It enables a more expressive and functional programming style in C++.
5) Are algorithm functions more efficient than manual loops, and why?
Yes, algorithm functions are generally more customized and reliable than hand-written loops. They are part of STL and benefit from years of testing and performance tuning. They make the code easier to understand and are less error-stricken. Instead of focusing on how to iterate, developers focus on what to achieve, making code more declarative.