拥有所有三种情况(a b)允许您拥有Total Ordering。但是如果你只指定一种情况——只指定一个 Weak Ordering。差异源于数学——但为了简化问题:使用前一种方案,您确实关心如何对相互关联的元素进行排序,而使用后一种方案,您不关心 一定在乎。
var list = [
{ age: 65, name: 'Tony'},
{ age: 24, name: 'Joe'},
{ age: 24, name: 'Susan' } // Joe and Susan are tied,
{ age: 5, name: 'Alice'},
];
假设我们按年龄对上述员工列表进行排序。总订单,我们保证有订单:Alice、Joe、Susan、Tony。因此,虽然 Joe 和 Susan 的年龄相同,但排序后仍保留了他们的相对顺序。然而,对于弱排序,我们将首先拥有 Alice,最后拥有 Tony,但 Joe 和 Susan 的顺序可供选择。这些员工的年龄相同,因此并列(平等)。这对于弱排序是不利的,因为弱排序没有指定如何在结果中排序关系——它是模棱两可的!因此,使用弱排序:我们最终可能会得到结果:Alice、Susan、Joe、Tony。当排序算法保留了关系的顺序时,我们说它是 stable sort。
如果您的排序功能类似于Arrays.prototype.sort() 并期望总排序,您应该始终提供所有三种情况!如果您不这样做:1. 已绑定的元素可能无法正确排序,2. 浏览器可能会感到困惑并且排序算法可能无法正确排序所有元素(即使没有任何绑定!)。
// (*) Array.prototype.sort expects total ordering
// ... so three cases needed
sort(list, function(a, b) { // (*)
if (a.age < b.age) return -1;
if (a.age > b.age) return 1;
return 0;
});
如果您使用的排序功能预期弱排序,您将只提供一种情况。 C++ 标准库提供了一个期望弱排序的函数的完美示例。
// (*) C++ STL uses weak orderings ...
// ... so only one case needed
struct Employee { int age; string name };
vector<Employee> employees = {
{ 65, "Tony" },
{ 24, "Joe" },
{ 24, "Susan" },
{ 5, "Alice" }
};
struct Sorter {
bool operator()(const Employee &e1, const Employee &e2) const {
return e1.age < e2.age; // (*)
}
};
sort(employees.begin(), employees.end(), Sorter());
这里,你只需要在排序函数中提供一个 case a C++ Reference for sort:
comp ... 返回的值指示作为第一个参数传递的元素是否被认为在其定义的特定严格弱排序中的第二个之前... 等效元素是 不保证保持原来的相对顺序
事实证明,C++ 标准库的原始设计者 Alexander Stepanov,可能是 did not want 使用弱排序并且更喜欢使用全排序(比如 Javascript!)——可能是为了防止这些与关系的歧义.事实上,许多其他语言(包括Java 和Python)使用总排序来进行排序功能。总排序很棒,因为它们消除了歧义,因此您应该提供所有三种情况的效果。