释义
该函数接受三个参数,stable_sort(first ,last ,cmp)(这里只是简单表示一下,并不是函数原型, cmp可以不用,默认为升序);这个函数的作用是对容器进行排序,并保证其稳定性(相等元素排序前后的相对位置不变)。
Sorts the elements in the range [__first,__last) in ascending order, such that for each iterator i in the range [__first,__last-1), __comp((i+1),i) is false. The relative ordering of equivalent elements is preserved, so any two elements x and y in the range [__first,__last) such that __comp(x,y) is false and __comp(y,x) is false will have the same relative ordering after calling stable_sort().
问题
cmp参数
下面是关于cmp函数的相关介绍
Binary function that accepts two elements in the range as arguments, and returns a value convertible to `bool`. The value returned indicates whether the element passed as first argument is considered to go before the second in the specific _strict weak ordering_ it defines.
The function shall not modify any of its arguments.
This can either be a function pointer or a function object.
cmp()函数的参数不可以是引用(但可以用是 常引用 或 值传递)举一个例子吧
/* 省略函数体 */bool cmp_1(int x, int y){} //值传递,允许bool cmp_2(const int &x, const int &y){} //常引用,允许bool cmp_3(int &x, int &y){} //引用,不允许
cmp比较源码
这里有一些让人费解的地方,对于以下两个函数来说,stable_sort()产生的结果是一样的吗?
bool cmp_1(int x,int y) {return x > y;
}bool cmp_2(int x,int y) {return x >= y;
}
思考一下,如果传入 x 的值和传入 y 的值在相等的情况下是否是一样的(这里包括稳定性),举个例子(用结构体帮助观察相对位置是否发生改变)
#include <iostream>
#include <vector>
#include <string>
#include <algorithm> struct Student { std::string str; int num;
}; bool cmp_1(const Student &x, const Student &y) { return x.num > y.num; } bool cmp_2(const Student &x, const Student &y) { return x.num >= y.num; } int main() { auto *p = new Student[]{{"a", 2}, {"b", 2}}; /* 正确 */std::stable_sort(p, p + 2, cmp_1); std::cout << p->str << ' ' << (p + 1)->str << std::endl; /* 错误 */std::stable_sort(p, p + 2, cmp_2); std::cout << p->str << ' ' << (p + 1)->str; delete[] p; return 0;
}/*
输出的结果是:a bb a
*/
可以看出 cmp_1 和 cmp_2 的结果是不同的,为什么 cmp_2 作为参数时stable_sort()不保证容器的稳定性呢? 这涉及到”函数源码“了?
Sorts the elements in the range [__first,__last) in ascending order, such that for each iterator i in the range [__first,__last-1), __comp(*(i+1),*i) is false.
这里要保证 __comp(*(i+1),*i) is false
,这个与我一直以为的__comp(*i,*(i+1)) is true
是不同的,所以 cmp_ 2 return x >= y
在遇到相等元素时会返回 true 不满足这个要求,所以会出错,这是第一个要注意的点。
第二个要注意的是满足Strict Weak Ordering
有以下几点要求:
1.Irreflexivity: f(x, x) must be false.
2.Antisymmetry: f(x, y) implies !f(y, x)
3.Transitivity: f(x, y) and f(y, z) imply f(x, z).
参考
- https://cplusplus.com/reference/algorithm/stable_sort/
- https://www.boost.org/sgi/stl/StrictWeakOrdering.html