C++ Algorithm Functions - C++ Programming Tutorial
C++ Course / STL Algorithm / C++ Algorithm Functions

C++ Algorithm Functions

BLUF: Mastering C++ Algorithm Functions is a critical step in becoming a proficient C++ developer. This lesson provides a deep dive into the syntax, performance considerations, and real-world applications of this concept.
Key Performance Insight: C++ Algorithm Functions

C++ is renowned for its efficiency. Learn how C++ Algorithm Functions enables low-level control and high-performance computing in the tutorial below.

In C++, the standard template library (STL) offers a robust set of fundamental functions under the <algorithm> header. These functions are beneficial for various tasks involving sequences like arrays, vectors, lists, and different types of containers. Algorithm functions are versatile and work with iterators, enabling their application across multiple container varieties.

Types of Algorithm

There are primarily two categories of algorithms. These include:

  • Immutable Algorithms
  • Mutable Algorithms

Now, we will discuss these algorithms one by one.

Non-Mutating Algorithms

In C++, non-modifying algorithms function on a series of elements while maintaining their original values. They are primarily employed for performing searches, comparisons, and examinations on different elements. These algorithms are ideal for fetching data without altering the container's contents. Popular instances comprise of find, used to search for a specific value, and count, which tallies the occurrences of a particular element.

These functions are effective, maintain data integrity, and serve as essential utilities for examining or validating elements within STL containers like vectors, linked lists, and arrays.

Mutating Algorithms

In C++, mutating algorithms refer to those algorithms that modify or reorganize the elements within a specified range. Unlike non-mutating algorithms, these operations directly change the original container without generating a new one. The C++ standard library offers a variety of mutating algorithms including functions like sort, reverse, rotate, partition, remove, and more. These algorithms are frequently employed for performing in-place data manipulations with high efficiency.

Member Functions of C++ Algorithm

Here is a compilation of all the member functions available for maps:

Standard Non-Modifying Sequence Algorithms

The provided table displays various typical non-altering sequence functions applied 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's consider a scenario to demonstrate the unaltered sequence operations in C++.

Example

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:

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 provided table displays various modifying sequence operations commonly utilized 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's consider an example to showcase the manipulation of sequence operations in C++.

Example

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:

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 provided table displays various partition operations commonly utilized 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's consider an example to illustrate the partition functions in C++.

Example

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:

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 provided table displays various sorting algorithms utilized in 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's consider an example to showcase the sorting functionalities in C++.

Example

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:

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 provided table displays various binary search functions commonly utilized 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's consider a scenario to illustrate the binary search procedures in C++.

Example

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:

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 provided table displays various merge operations commonly utilized 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's consider an example to illustrate the merging operations in C++.

Example

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:

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 provided table displays various heap functions commonly employed in 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's consider an illustration to showcase the heap manipulations in C++.

Example

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:

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 provided table displays various minimum and maximum operations commonly utilized 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's consider a scenario to illustrate the minimum and maximum operations in C++.

Example

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:

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 provided table displays various additional functions that are beneficial 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 summary, the C++ algorithm function serves as a vital set of tools for effective and expressive coding, made accessible via the header within the standard template library (STL). These functions encapsulate intricate low-level iteration processes and offer tailored, clear-cut functionalities for activities like data searching, sorting, altering, comparing, and converting.

C++ Algorithm FAQs

1) What is the purpose of the __PRESERVE_17__ header in C++?

In C++, the <algorithm> header offers a diverse range of predefined functions for tasks like sorting, searching, counting, and altering data. This header streamlines the code by substituting repetitive code with reusable algorithms. These functions interact seamlessly with containers through iterators, enhancing the clarity, performance, and abstraction of C++ programming.

2) Do C++ algorithm functions work with all types of containers?

Algorithm functions work on iterators rather than containers directly, allowing compatibility with various STL containers like vectors, lists, and arrays. This design enhances flexibility in handling tasks. However, certain algorithms mandate specific iterator types, for instance, sort necessitates random-access iterators.

3) What is the difference between std::sort and std::stable_sort?

In C++, the std::sort methods maintain quick and rearranged elements in sequence but do not retain the initial arrangement of identical elements. Conversely, the std::stablesort function preserves the original positions of similar elements, ensuring the order remains intact when necessary. Although sort is faster, stablesort guarantees stability in scenarios involving multiple levels of sorting.

4) How does the algorithm function support the custom logic through predicates or lambdas?

Many algorithms support a user-defined criterion, known as a predicate, which can be a function pointer, functor, or lambda expression. This feature enables the application of custom conditions during various operations like filtering, sorting, and searching. Lambdas are commonly employed for concise and inline logic implementation, fostering a more expressive and functional programming approach within C++.

5) Are algorithm functions more efficient than manual loops, and why?

Yes, algorithm functions are typically more personalized and dependable compared to manually written loops. They are integral to the Standard Template Library (STL) and have undergone extensive testing and optimization over the years. This results in code that is easier to comprehend and less prone to errors. By shifting the focus from the iteration process to the desired outcome, developers can write more declarative code.

Input Required

This code uses input(). Please provide values below:

Logic Practice
Install Logic Practice
Add to home screen for a faster app-like experience