比尤果网做的好的网站,桂林临桂区建设局网站,wordpress整体搬迁,[8dvd]flash网站源文件 flash整站源码泛型算法
algorithm定义了大约 80 个标准算法。 它们操作由一对迭代器定义的#xff08;输入#xff09;序列或单一迭代器定义的#xff08;输出#xff09;序列。 当对两个序列进行拷贝、比较操作时#xff0c;第一个序列由一对迭代器[b,e)表示#xff0c;但第…泛型算法
algorithm定义了大约 80 个标准算法。 它们操作由一对迭代器定义的输入序列或单一迭代器定义的输出序列。 当对两个序列进行拷贝、比较操作时第一个序列由一对迭代器[b,e)表示但第二个序列只由一个迭代器b2表示b2指出了序列的起始位置。 应当保证第二个序列包含足够多的的元素供算法使用。 大多数标准库算法返回迭代器特别是它们不返回结果的容器。 大多数标准库算法都有两个版本
一个“普通”版本使用常规操作如和完成其任务。另一个版本接受关键操作参数 在某些情况下实参既可以解释为谓词也可以解释为值。
不修改序列的算法
for_each()
最简单的算法是 for_each()它简单地对序列中的每个元素执行指定操作。 vectorint v{ 2,4,6,8 };for_each( v.begin(), v.end(), [](int x) {cout x ; } );/* 输出 2 4 6 8 */算法功能f for_each(b,e,f);对[b,e)中的每个 x 执行f(x)返回 f
序列谓词 vectorint v{ 2,4,6,8 };auto flag all_of(v.begin(), v.end(), [](int x) { return x 0; });cout flag endl; // v 中的每个元素大于 0 输出 1当一个序列谓词失败时它不会告知我们是哪个元素导致了失败。 vectorint v{ 0,4,8,3 };auto flag any_of(v.begin(), v.end(), [](int x) { return x 5; });cout flag endl; //有元素大于 5 但不知道是哪个元素大于5算法功能all_of(b,e,f);[b,e)中所有 x 都满足f(x)吗any_of(b,e,f);[b,e)中某个 x 满足f(x)吗none_of(b,e,f);[b,e)中所有 x 都不满足f(x)吗
count() vectorint v{ 1,0,1,1,3 };cout count(v.begin(), v.end(), 1) endl; // 1 的数目为 3输出 3算法功能x count(b,e,v);x 为[b,e)中满足v*p的元素*p的数目x count_if(b,e,f);x 为[b,e)中满足f(*p)的元素*p的数目
find()
find() 系列算法顺序搜索具有特定值或令谓词为真的元素。 谓词是一个可调用的表达式其结果是一个能用作条件的值。 算法 find() 和 find_if() 都返回一个迭代器分别指向匹配给定值和给定谓词的第一个元素。 vectorchar v{ e,E,d,E,A};auto p find(v.begin(),v.end(),E);cout *p endl; //输出 Ecout *(p 1) endl; //输出 d算法 find_first_of() 查找序列中与另一个序列中元素相等的第一个元素。 vectorchar v{ e,E,d,B,b };arraychar, 4 arr{ A,B,C,D };auto p find_first_of( v.begin(),v.end(),arr.begin(),arr.end() );cout *p endl; //输出 B算法功能p find(b,e,v);p 指向[b,e)中第一个满足v*p的元素p find_if(b,e,f);p 指向[b,e)中第一个满足f(*p)的元素p find_if_not(b,e,f);p 指向[b,e)中第一个满足!f(*p)的元素p find_first_of(b1,e1,b2,e2);p 指向[b1,e1)中第一个满足*p*q的元素其中 q 指向[b2,e2)中的某个元素p find_first_of(b1,e1,b2,e2,f);p 指向[b1,e1)中第一个满足f(*p,*q)的元素其中 q 指向[b2,e2)中的某个元素p adjacent_find(b,e);p 指向[b,e)中第一个满足*p*(p1)的元素p adjacent_find(b,e,f);p 指向[b,e)中第一个满足f(*p,*(p1))的元素p find_end(b1,e1,b2,e2);p 指向[b1,e1)中最后一个满足*p*q的元素其中 q 指向[b2,e2)中的某个元素p find_end(b1,e1,b2,e2,f);p 指向[b1,e1)中最后一个满足f(*p,*q)的元素其中 q 指向[b2,e2)中的某个元素
equal()
算法 equal() 比较两个序列中的元素是否都相同。 vectorchar v{ A,B,C,D,b };arraychar, 4 arr{ A,B,C,D };auto b equal( v.begin(),v.end() -1 ,arr.begin(),arr.end() );cout b endl; //输出 1 算法功能equal(b,e,b2);[b,e)和[b2,b2(e-b))中所有对应元素都满足v v2equal(b,e,b2,f);[b,e)和[b2,b2(e-b))中所有对应元素都满足f(v,v2)
mismatch()
算法 mismatch() 查找两个序列中第一对不匹配的元素返回指向这两个元素的迭代器。 并没有参数指出第二个序列的末尾算法假定第二个序列中至少包含与第一个序列一样多的元素。 vectorchar v{ A,B,e,D };arraychar, 4 arr{ A,B,C,D };auto p mismatch( v.begin(),v.end() ,arr.begin() );cout *(p.first) endl; //输出 ecout *(p.second) endl; //输出 C算法功能pair(p1,p2) mismatch(b,e,b2);p1 指向[b,e)中第一个满足!(*p1 *p2)的元素p2 指向[b2,b2(e-b))中对应的元素若不存在这样的元素则p1 epair(p1,p2) mismatch(b,e,b2,f);p1 指向[b,e)中第一个满足!f(*p1,*p2)的元素p2 指向[b2,b2(e-b))中对应的元素若不存在这样的元素则p1 e
search()
算法 search() 和 search_n() 查找给定序列是否是另一个序列的子序列。 vectorchar v{ E,A,B,C,D };arraychar, 3 arr{ A,B,C } ;auto p search(v.begin(), v.end(), arr.begin(), arr.end());cout *p endl; //输出 AA,B,C 是 E,A,B,C,D 的子序列算法功能p serach(b,e,b2,e2);p 指向[b,e)中第一个满足[p,p(e2-b2))中等于[b2,e2)的*pp serach(b,e,b2,e2,f);p 指向[b,e)中第一个满足[p,p(e2-b2))中等于[b2,e2)的*p用 f 比较元素p serach_n(b,e,n,v);p 指向[b,e)中第一个满足[p,pn)间所有元素的值均为 v 的位置p serach_n(b,e,n,v,f);p 指向[b,e)中第一个满足[p,pn)间每个元素*q均满足f(*p,v)的位置
修改序列的算法
transform()
数据写入操作不能超出目标序列的末尾。 arraychar, 4 arr{ A,B,C,D };vectorchar v{ E,A,B,C,Z};transform(arr.begin(), arr.end(), v.begin(), [](char x) { return x 32; });/* V 中的元素变为a b c d Z */输出和输入可能是同一个序列。 vectorchar v{ E,A,B,C,Z};transform(v.begin(), v.end(), v.begin(), [](char x) { return x 32; });/* V 中的元素变为e a b c z */算法功能p transform(b,e,out,f);对[b,e)中的每个元素*p1应用*q f(*p1)结果写入[out,out (e - b)中的对应元素*q p out (e - b)p transform(b,e,b2,out,f);对[b,e)中的每个元素*p1及其在[b2,b2 (e - b))中的对应元素*p2*应用*q f(*p1,*p2)结果写入[out,out (e - b)中的对应元素*q p out (e - b)
copy()
copy() 系列算法从一个序列拷贝至另一个序列。 为了读取一个序列需要一对迭代器描述起始位置和结尾位置为了向序列中写入数据则只需一个迭代器。 arrayint,4 arr { 1,3,5,7 };vectorint v{ 2,4,6,8 };auto p copy( arr.begin(),arr.end(),v.begin() ); /* v 内的元素变为 1 3 5 7 */cout * (p-1) endl; //输出 7p arr.end()数据写入操作不能超出目标序列的末尾但是可以使用一个插入器按需增长目标序列。 arrayint,4 arr { 1,3,5,7 };vectorint v{ 2,4,6,8 };copy(arr.begin(), arr.end(), back_inserter(v));/* v 内的元素变为 2 4 6 8 1 3 5 7 */拷贝算法的目标序列不一定是一个容器任何可用一个输出迭代器描述的东西都可以作为它的目标。
算法功能p copy(b,e,out);将[b,e)中所有元素拷贝至 [out,p) p out (e - b)p copy_if(b,e,out,f);将[b,e)中满足f(x)的元素 x 拷贝至[out,p)p copy_n(b,n,out);将[b,bn)间的前 n 个元素拷贝至 [out,p) p out np copy_backward(b,e,out);将[b,e)中的所有元素拷贝至 [out,p)从尾元素开始拷贝 p out (e - b)p move(b,e,out);将[b,e)中所有元素移动至 [out,p) p out (e - b)p move_backward(b,e,out);将[b,e)中的所有元素移动至 [out,p)从尾元素开始移动 p out (e - b)
unique()
算法 unique() 将不重复的元素移动到序列的头部并返回指向不重复元素末尾位置的迭代器。 vectorchar v{ A,A,C,E,E,B};auto p unique(v.begin(), v.end()); auto iter v.begin();while (iter ! p){cout *iter ;}cout endl;/* 输出 A C E B */为了从一个容器中删除重复元素必须显示地收缩容器。 vectorchar v{ A,A,C,E,E,B};auto p unique(v.begin(), v.end()); v.erase(p,v.end());算法功能p unique(b,e);移动[b,e]中的一些元素使得[b,p)中无连续重复元素p unique(b,e,f);移动[b,e]中的一些元素使得[b,p)中无连续重复元素“重复”由f(*p,*(p1))判定p unique_copy(b,e,out);将[b,e)中的元素拷贝至 [out,p)不拷贝连续重复元素p unique_copy(b,e,out,f);将[b,e)中的元素拷贝至 [out,p)不拷贝连续重复元素“重复”由f(*p,*(p1))判定
remove()
算法 remove() 删除序列末尾的元素它是通过将元素移动到左侧来实现“删除”的。 vectorchar v{ A,B,C,E,E,D };auto p remove(v.begin(), v.end(),E);auto iter v.begin();while (iter ! p){cout *iter ;}cout endl;/*输出A B C D*/算法功能p remove(b,e,v);从[b,e]中删除值为 v 元素使得[b,p)中的元素都满足!(*q v)p remove(b,e,f);从[b,e]中删除元素*q使得[b,p)中的元素都满足!f(*q)p remove_copy(b,e,out,v);将[b,e)中满足!(*q v)的元素拷贝至 [out,p)p remove_copy_f(b,e,out,f);将[b,e)中满足!f(*q)的元素拷贝至 [out,p)
raplace()
算法 raplace() 将新值赋予选定的元素。 vectorchar v{ E,A,E,B,C,D };replace(v.begin(), v.end(),E,F); // 将 E 替换为 F/* v 内的元素变为 F A F B C D */算法功能p raplace(b,e,v,v2);将[b,e)中满足*p v的元素替换为 v2p raplace(b,e,f,v2);将[b,e)中满足f(*p)的元素替换为 v2p raplace_copy(b,e,out,v,v2);将[b,e)中的元素拷贝至 [out,p)其中满足*p v的元素被替换为 v2p raplace_copy_f(b,e,out,f,v2);将[b,e)中的元素拷贝至 [out,p)其中满足f(*p,v)的元素被替换为 v2
rotable() 、 random_shuffle() 和 partition()
算法 rotable() 、 random_shuffle() 和 partition() 提供了移动序列中元素的系统方法。 rotable()以及洗牌和划分算法是用 swap() 来移动元素的。
rotable() vectorchar v{ A,B,C,D,E };auto p rotate(v.begin(),v.begin()2, v.end());/* v 内的元素变为 C D E A B */cout *p endl; // *p A算法功能p rotable(b,m,e);循环左移元素将[b,e]看作一个环首元素在尾元素之后将*(bi)移动到*( b (i(e-m))%(e-b) )*b移动到*mp b(e-m)p rotable_copy(b,m,e,out);将[b,e]中的元素循环左移拷贝至[out,p)
random_shuffle()
默认情况下random_shuffle() 用均匀分布随机数发生器洗牌序列。 即它选择序列元素的一个排列使得每种排列被选中的概率相等。 vectorchar v{ A,D,C,B,E };random_shuffle(v.begin(),v.end());/* v 内的元素变为 E D B C A */算法功能random_shuffle(b,e);洗牌[b,e]中的元素使用默认随机数发生器random_shuffle(b,e,f);洗牌[b,e]中的元素使用随机数发生器 fshuffle(b,e,f);洗牌[b,e]中的元素使用均匀分布随机数发生器 f
partition()
划分算法基于某种划分标准将序列分为两部分。 vectorchar v{ A,H,C,B,F };auto p partition(v.begin(), v.end(), [](char x) {return x E; });/* v 内的元素变为 A C B H F */cout *p endl; // *p H算法功能p partition(b,e,f);将满足f(*p1)的元素置于区间[b,p)内将其它元素置于区间[p,e)内p stable_partition(b,e,f);将满足f(*p1)的元素置于区间[b,p)内将其它元素置于区间[p,e)内保持相对顺序pair(p1,p2) partition_copy(b,e,out1,out2,f);将[b,e)中满足f(*p)的元素拷贝到[out1,p1)内将[b,e)中满足!f(*p)的元素拷贝到[out2,p2)内p partition_point(b,e,f);对[b,e)p 指向满足all_of(b,p,f)且none_of(b,p,f)的位置is_partitioned(b,e,f);[b,e)中满足f(*p)的元素都在满足!f(*p)的元素之前吗
排列
例打印序列 ABC 的所有排列组合 vectorchar v{ A,B,C };bool x true;while ( x ){x next_permutation(v.begin(), v.end());for (auto i : v)cout i ;cout endl;}/* 输出A C BB A CB C AC A BC B AA B C*/算法 next_permutation() 接受一个序列将其变换为下一个排列。 下一个的定义基于这样一个假设所有的排列组合已按字典序排序。 如果存在”下一个“排列组合next_permutation() 返回 true否则它将序列变换为升序中排在第一位的排列组合例中的 ABC并返回 false
算法功能x next_permutation(b,e);将[b,e)变换为字典序上的下一个排列x next_permutation(b,e,f);将[b,e)变换为字典序上的下一个排列用 f 比较元素x prev_permutation(b,e);将[b,e)变换为字典序上的前一个排列x prev_permutation(b,e,f);将[b,e)变换为字典序上的前一个排列用 f 比较元素is_permutation(b,e,b2);[b2,b2(e-b))是[b,e)的一个排列is_permutation(b,e,f);[b2,b2(e-b))是[b,e)的一个排列用 f(*q,*p) 比较元素
fill()
fill() 系列算法提供了向序列元素赋值和初始化元素的方法。 算法 fill() 反复用指定值进行赋值。 vectorchar v{ A,H,C,B,F };fill(v.begin(), v.end(), E);/* v 内的元素变为 E E E E E */算法 generate() 则通过反复调用其函数实参得到的值进行赋值。 vectorchar v{ A,H,C,B,F };int i 0;generate( v.begin(), v.end(), [i] { i; return A i; } );/* v 内的元素变为 B C D E F */算法 uninitialized_fill() 或 uninitialized_copy() 的目标元素必须是内置类型或是未初始化的。
算法功能fill(b,e,v);将 v 赋予[b,e)中的每一个元素p fill_n(b,n,v);将 v 赋予[b,bn)中的每一个元素p bngenerate(b,e,f);将 f() 赋予[b,e)中的每一个元素p generate_n(b,n,f);将 f() 赋予[b,bn)中的每一个元素p bnuninitialized_fill(b,e,v);将[b,e)中的每一个元素初始化为 vp uninitialized_fill_n(b,n,v);将[b,bn)中的每一个元素初始化为 vp bnuninitialized_copy(b,e,out);将[out,out(e-b))中的每一个元素初始化为[b,e)中对应的元素p out(e-b) p uninitialized_copy_n(b,n,out);将[out,outn]中的每一个元素初始化为[b,bn)中对应的元素p outn
排序和搜索
排序
默认的比较操作是运算符值 a 和 b 的相等性通过!(ab)!(ba)来判定而不是使用运算符。 算法 sort() 要求使用随机访问迭代器。 基础的 sort() 算法很高效平均时间复杂性为 O ( N ∗ log ( N ) ) O(N*\log(N)) O(N∗log(N))。。 如果需要一个稳定的排序算法可以使用 stable_sort()其平均时间复杂性为 O ( N ∗ log ( N ) log ( N ) ) O(N*\log(N)\log(N)) O(N∗log(N)log(N))当系统有足够的额外内存时可缩短为 O ( N ∗ log ( N ) ) O(N*\log(N)) O(N∗log(N))。 算法 stable_sort() 可以保证相等元素的相对顺序然而 sort() 则不能保证。 如果需要由 partial_sort() 排序的元素数少于元素总数则其时间复杂性接近 O ( N ) O(N) O(N)。 算法 partial_sort_copy() 的目标必须是一个随机访问迭代器。 算法 nth_element() 只需将升序结果中排在第 n 位的元素放置到正确位置即可即之前的元素都不大于它之后的元素都不小于它。
算法功能sort(b,e);排序[b,e)sort(b,e,f);排序[b,e)用f(*p,*q)作为比较标准stable_sort(b,e);排序[b,e)保持相等元素的相对顺序stable_sort(b,e,f);排序[b,e)保持相等元素的相对顺序用f(*p,*q)作为比较标准partial_sort(b,m,e);部分排序[b,e)令[b,m)有序即可[m,e)不必有序partial_sort(b,m,e,f);部分排序[b,e)令[b,m)有序即可[m,e)不必有序用f(*p,*q)作为比较标准p partial_sort_copy(b,e,b2,e2);部分排序[b,e)排好前e2-b2或前e-b个元素拷贝到[b2,e2)p 为 e2 和 b2 (e-b) 中的较小者p partial_sort_copy(b,eb2,e2,f);部分排序[b,e)排好前e2-b2或前e-b个元素拷贝到[b2,e2)p 为 e2 和 b2 (e-b) 中的较小者用 f 比较元素is_sort(b,e);[b,e)已排序is_sort(b,e,f);[b,e)已排序用 f 比较元素p is_sort_until(b,e);p 指向[b,e)中第一个不符合升序的元素p is_sort_until(b,e,f);p 指向[b,e)中第一个不符合升序的元素用 f 比较元素nth_element(b,n,e);*n的位置恰好是[b,e)排序后它应处的位置即[b,n)中的元素都 *n且[n,e)中的元素都 *nnth_element(b,n,e,f);*n的位置恰好是[b,e)排序后它应处的位置即[b,n)中的元素都 *n且[n,e)中的元素都 *n用 f 比较元素reverse(b,e);将[b,e)中的元素逆序排序p reverse_copy(b,e,out);将[b,e)中的元素逆序拷贝至[out,p)
二分搜索
binary_serach() 系列算法提供有序序列上的二分搜索。 一旦序列已排序就可以使用二分搜索查找元素了。
算法功能p lower_bound(b,e,v);p 指向[b,e)中 v 首次出现的位置p lower_bound(b,e,v,f);p 指向[b,e)中 v 首次出现的位置用 f 比较元素p upper_bound(b,e,v);p 指向[b,e)中第一个大于 v 的元素p upper_bound(b,e,v,f);p 指向[b,e)中第一个大于 v 的元素用 f 比较元素binary_search(b,e,v);v 在有序序列[b,e)中吗binary_search(b,e,v,f);v 在有序序列[b,e)中吗用 f 比较元素pair(p1,p2) equal_range(b,e,v);[p1,p2)是[b,e)中值为 v 的子序列通常用二分搜索查找 vpair(p1,p2) equal_range(b,e,v,f);[p1,p2)是[b,e)中值为 v 的子序列通常用二分搜索查找 v用 f 比较元素
merge()
算法 merge() 将两个有序序列合并为一个序列。 算法 merge() 可以接受不同类别的序列和不同类型的元素。
算法功能p merge(b,e,b2,e2,out);合并两个有序序列[p1,p2)与[b,e)结果写入[out,p)p merge(b,e,b2,e2,out,f);合并两个有序序列[p1,p2)与[b,e)结果写入[out,outp)用 f 比较元素inplace_merge(b,m,e);原址合并将两个有序子序列[b,m)与[m,e)合并为有序序列[b,e)inplace_merge(b,m,e,f);原址合并将两个有序子序列[b,m)与[m,e)合并为有序序列[b,e)用 f 比较元素
集合算法
这些算法将序列当作一个元素集合来处理并提供基本的集合操作。 输入序列应是排好序的输出序列也会被排序。
算法功能includes(b,e,b2,e2);[b,e)中的所有元素也都在[b2,e2)中includes(b,e,b2,e2,f);[b,e)中的所有元素也都在[b2,e2)中用 f 比较元素p set_union(b,e,b2,e2,out);创建一个有序序列[out,p) 包含[b,e)和[b2,e2)中的所有元素p set_union(b,e,b2,e2,out,f);创建一个有序序列[out,p) 包含[b,e)和[b2,e2)中的所有元素用 f 比较元素p set_intersection(b,e,b2,e2,out);创建一个有序序列[out,p) 包含[b,e)和[b2,e2)中共同的元素p set_intersection(b,e,b2,e2,out,f);创建一个有序序列[out,p) 包含[b,e)和[b2,e2)中共同的元素用 f 比较元素p set_difference(b,e,b2,e2,out);创建一个有序序列[out,p) 其元素在[b,e)中但不在[b2,e2)中p set_difference(b,e,b2,e2,out,f);创建一个有序序列[out,p) 其元素在[b,e)中但不在[b2,e2)中用 f 比较元素p set_symmetric_difference(b,e,b2,e2,out);创建一个有序序列[out,p) 其元素在[b,e)中或在[b2,e2)中但不同时在两者中p set_symmetric_difference(b,e,b2,e2,out,f);创建一个有序序列[out,p) 其元素在[b,e)中或在[b2,e2)中但不同时在两者中用 f 比较元素
堆
堆是一种按最大值优先的方式组织元素的紧凑数据结构。 堆算法允许将一个随机访问序列作为堆处理。 堆的关键特点是提供了快速插入新元素和快速访问最大元素的能力其主要用途是实现优先队列。
算法功能make_heap(b,e);将[b,e)整理为一个堆make_heap(b,e,f);将[b,e)整理为一个堆用 f 比较元素push_heap(b,e);将*(e-1)添加到堆[b,e-1)中使得[b,e)还是一个堆push_heap(b,e,f);将*(e-1)添加到堆[b,e-1)中使得[b,e)还是一个堆用 f 比较元素pop_heap(b,e);从堆[b,e)中删除最大值*b与*(e-1)交换后删除*(e-1)[b,e-1)保持堆结构pop_heap(b,e,f);从堆[b,e)中删除最大值*b与*(e-1)交换后删除*(e-1)[b,e-1)保持堆结构用 f 比较元素sort_heap(b,e);排序堆[b,e)sort_heap(b,e,f);排序堆[b,e)用 f 比较元素is_heap(b,e);[b,e)是一个堆吗is_heap(b,e,f);[b,e)是一个堆吗用 f 比较元素p is_heap_until(b,e);p 是满足[b,p)堆的最大位置p is_heap_until(b,e,f);p 是满足[b,p)堆的最大位置用 f 比较元素
lexicographical_compare()
字典序比较就是我们用来排序字典中单词的规则。
算法功能lexicographical_compare(b,e,b2,e2);[b,e) [b2,e2)lexicographical_compare(b,e,b2,e2,f);[b,e) [b2,e2)用 f 比较元素
最大值和最小值
如果比较两个左值返回的是指向结果的引用否则返回一个右值。 但是接受左值的版本接受的是 const 左值因此永远也不能修改这些函数的返回结果。
算法功能x min(a,b);x 是 a 和 b 中的较小者x min(a,b,f);x 是 a 和 b 中的较小者用 f 比较元素x min({elem});x 是 {elem} 中的最小元素x min({elem},f);x 是 {elem} 中的最小元素用 f 比较元素x max(a,b);x 是 a 和 b 中的较大者x max(a,b,f);x 是 a 和 b 中的较大者用 f 比较元素x max({elem});x 是 {elem} 中的最大元素x max({elem},f);x 是 {elem} 中的最大元素用 f 比较元素pair(x,y) minmax(a,b);x 为 min(a,b)y 为 max(a,b)pair(x,y) minmax(a,b,f);x 为 min(a,b,f)y 为 max(a,b,f)pair(x,y) minmax({elem});x 为 min({elem})y 为 max({elem})pair(x,y) minmax({elem},f);x 为 min({elem},f)y 为 max({elem},f)p min_element(b,e);p 指向[b,e)中的最小元素或 ep min_element(b,e,f);p 指向[b,e)中的最小元素或 e用 f 比较元素p max_element(b,e);p 指向[b,e)中的最大元素或 ep max_element(b,e,f);p 指向[b,e)中的最大元素或 e用 f 比较元素pair(x,y) minmax_element(b,e);x 为 min_element(b,e)y 为 max_element(b,e)pair(x,y) minmax_element(b,e,f);x 为 min_element(b,e,f)y 为 max_element(b,e,f)