std::minmax_element

来自cppreference.com
< cpp‎ | algorithm
 
 
算法库
执行策略 (C++17)
不修改序列的操作
(C++11)
(C++11)
(C++11)
(C++17)
修改序列的操作
未初始化存储上的操作
划分操作
排序操作
(C++11)
二分搜索操作
集合操作(在已排序范围上)
堆操作
(C++11)
最小/最大操作
(C++11)
minmax_element
(C++11)
(C++17)
排列
数值运算
C 库
 
定义于头文件 <algorithm>
(1)
template< class ForwardIt >

std::pair<ForwardIt,ForwardIt>

    minmax_element( ForwardIt first, ForwardIt last );
(C++11 起)
(C++17 前)
template< class ForwardIt >

constexpr std::pair<ForwardIt,ForwardIt>

    minmax_element( ForwardIt first, ForwardIt last );
(C++17 起)
template< class ExecutionPolicy, class ForwardIt >

std::pair<ForwardIt,ForwardIt>

    minmax_element( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last );
(2) (C++17 起)
(3)
template< class ForwardIt, class Compare >

std::pair<ForwardIt,ForwardIt>

    minmax_element( ForwardIt first, ForwardIt last, Compare comp );
(C++11 起)
(C++17 前)
template< class ForwardIt, class Compare >

constexpr std::pair<ForwardIt,ForwardIt>

    minmax_element( ForwardIt first, ForwardIt last, Compare comp );
(C++17 起)
template< class ExecutionPolicy, class ForwardIt, class Compare >

std::pair<ForwardIt,ForwardIt>

    minmax_element( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, Compare comp );
(4) (C++17 起)

寻找范围 [first, last) 中最小和最大的元素。

1)operator< 比较元素。
3) 用给定的二元比较函数 comp 比较元素。
2,4)(1,3) ,但按照 policy 执行。这些重载仅若 std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> 为 true 才参与重载决议。

目录

[编辑] 参数

first, last - 定义要检验的元素范围的迭代器
policy - 所用的执行策略。细节见执行策略
cmp - 比较函数对象(即满足比较 (Compare) 要求的对象),若若 *a 小于 *b ,则返回 ​true

比较函数的签名应等价于如下者:

 bool cmp(const Type1 &a, const Type2 &b);

签名不需要拥有 const & ,但函数对象必须不修改传递给它的对象。
类型 Type1Type2 必须使得 ForwardIt 类型的对象能在解引用后隐式转换到这两个类型。 ​

类型要求
-
ForwardIt 必须满足 ForwardIterator 的要求。

[编辑] 返回值

以指向最小元素的迭代器为第一元素,以指向最大元素的迭代器为第二元素的 pair 。若范围为空则返回 std::make_pair(first, first) 。若多个元素等价于最小元素,则返回指向首个这种元素的迭代器。若多个元素等价于最大元素,则返回指向最后一个这种元素的迭代器。

[编辑] 复杂度

至多应用谓词 max(floor(3/2(N−1)), 0) 次,其中 N = std::distance(first, last)

[编辑] 异常

拥有名为 ExecutionPolicy 的模板参数的重载按下列方式报告错误:

  • 若作为算法一部分调用的函数的执行抛出异常,且 ExecutionPolicy 是三个标准策略之一,则调用 std::terminate 。对于任何其他 ExecutionPolicy ,行为是实现定义的。
  • 若算法无法分配内存,则抛出 std::bad_alloc

[编辑] 注意

此算法不仅在效率上异于 std::make_pair(std::min_element(), std::max_element()) ,而且此算法寻找最后的最大元素,而 std::max_element 寻找首个最大元素。

[编辑] 可能的实现

版本一
template<class ForwardIt>
std::pair<ForwardIt, ForwardIt> 
    minmax_element(ForwardIt first, ForwardIt last)
{
    return std::minmax_element(first, last, std::less<>());
}
版本二
template<class ForwardIt, class Compare>
std::pair<ForwardIt, ForwardIt> 
    minmax_element(ForwardIt first, ForwardIt last, Compare comp)
{
    std::pair<ForwardIt, ForwardIt> result(first, first);
 
    if (first == last) return result;
    if (++first == last) return result;
 
    if (comp(*first, *result.first)) {
        result.first = first;
    } else {
        result.second = first;
    }
    while (++first != last) {
        ForwardIt i = first;
        if (++first == last) {
            if (comp(*i, *result.first)) result.first = i;
            else if (!(comp(*i, *result.second))) result.second = i;
            break;
        } else {
            if (comp(*first, *i)) {
                if (comp(*first, *result.first)) result.first = first;
                if (!(comp(*i, *result.second))) result.second = i;
            } else {
                if (comp(*i, *result.first)) result.first = i;
                if (!(comp(*first, *result.second))) result.second = first;
            }
        }
    }
    return result;
}

[编辑] 示例

#include <algorithm>
#include <iostream>
#include <vector>
 
int main()
{
    std::vector<int> v = { 3, 9, 1, 4, 2, 5, 9 };
 
    auto result = std::minmax_element(v.begin(), v.end());
    std::cout << "min element at: " << (result.first - v.begin()) << '\n';
    std::cout << "max element at: " << (result.second - v.begin()) << '\n';
}

输出:

min element at: 2
max element at: 6

[编辑] 参阅

返回区间内的最小元素
(函数模板) [编辑]
返回区间内的最大元素
(函数模板) [编辑]