icomparer 实现 class 如何决定数组项的排序顺序?
How does icomparer implementing class decide sorting order on the array items?
IComparer.Compare函数的return值是如何决定排序操作顺序的? return 值在决定排序顺序时的意义是什么? Array.Sort() 的流程是如何发生的?
例如:
int[] ii = new int[3] { 8,1,4};
Array.Sort(ii, new myComp1());
有没有办法理解排序操作的流程。我的意思是如果我想决定一个特定的排序顺序,那么我应该如何写 if-else 条件或 return 值?
class myComp1 : IComparer<int>
{
public int Compare(int x, int y)
{
if (x == y)
return 1;
else if (x > y)
return -1;
else
return 0;
}
}
例如,在下面给出的代码中,我不明白比较器函数的 return 值的意义,无论它是按升序还是按降序或某种随机顺序。 MSDN没有解释的很清楚。
任何帮助。
我也想了解一下:下面代码中的Array.Sort()是不是先比较8和1,再比较1和4,再比较1和8?此执行是否有任何流程,以便作为程序员我可以在编写实际代码之前弄清楚它?
谢谢。
int[] kk = new int[3] { 8,1,4};
Array.Sort(kk, new myComp2());
class myComp2 : IComparer<int>
{
public int Compare(int x, int y)
{
int res = 0;
if (x == y)
return 1;
else if (x > y)
return 2;
else
return 3;
return res;
}
}
Array.Sort
或 .NET 中的任何其他 .Sort
变体按升序排序项目。
当你实现你的比较器时,结果的含义很简单:
- 小于 0:
x
小于 y
- 大于 0:
x
大于 y
- 等于 0:
x
等于 y
- 比较操作必须是可传递的,例如1 ≤ 4 ≤ 8.
集合中项目的比较顺序取决于 sorting algorithm,因此无法保证 Compare
调用的特定顺序。
具有 IComparer<>
是一个很好的抽象,在其他场景中也很有用,而不仅仅是排序。
如果您想要任何特定的项目顺序,您可以定义保留传递性的比较器规则,或者可能不使用 .Sort
。
更新
作为程序员,你应该思考:
public int Compare(int x, int y)
{
// OPTION 1
if (x < y)
return -1; // X is less than Y, place X before Y - acsending order
...
// OPTION 2
if (x < y)
return 1; // X is less than Y, place X after Y - descending order
...
return 0; // keep order of X and Y if possible (stable comparison only)
}
更新 2
好的,假设我们有一个这样定义的比较器:
interface IComparer<T>
{
SortPlacement Compare(T x, T y);
}
其中SortPlacement
定义如下:
enum SortPlacement
{
Try_To_Keep_Same_Order_Of_X_and_Y = 0,
Place_X_Before_Y_Ascending_Order = -1, // or any negative number
Place_X_After_Y_Descending_Order = 1, // or any positive number
}
当你实现你的比较器时,你非常清楚:
public SortPlacement Compare(int x, int y)
{
// OPTION 1
if (x < y)
return SortPlacement.Place_X_Before_Y_Ascending_Order;
...
// OPTION 2
if (x < y)
return SortPlacement.Place_X_After_Y_Descending_Order;
...
// OPTION 3
return SortPlacement.Try_To_Keep_Same_Order_Of_X_and_Y;
}
现在忘记愚蠢的枚举类型并将其替换为整数 - 这是一个简单的约定。
排序算法使用 Compare
方法的 return 值来确定在对两个数字进行排序时,哪个数字应该排在另一个数字之前。
鉴于此签名:public int Compare(int x, int y)
return 值表示:
returnValue < 0
: x < y
returnValue == 0
: x == y
returnValue > 0
: x > y
所以如果方法 returns 0
,数字被认为是相等的(并且它们的顺序不会改变)。如果它 returns -1
,那么第一个数字应该 在 第二个数字之前。如果它 returns 1
,那么第一个数字应该在 第二个数字 之后。
现在,由于您已经更改了 Compare
方法中的定义,您将获得与通常预期不同的项目顺序,但这就是允许自定义比较器的全部意义所在 - 它留下关于 "which comes first" 的决定给你。
但是,由于 return 值实际上仅被评估为 0
、less than zero
或 greater than zero
,在您的第二个示例中,因为您总是 return 大于零的值,顺序将是未知的(这将取决于所使用的算法)。我这样说是因为当我用 {1, 5, 3}
测试它时它颠倒了它们,但是当我使用 {1, 5, 3, 4, 8}
时,顺序没有改变。
请注意,由于 comp2
return 中的所有案例的值都大于零,因此可以重写:
public int Compare(int x, int y) { return 1; }
另外,Array.Sort
的源代码在网上,如果你想看排序算法的使用,但你似乎更感兴趣什么
IComparer.Compare函数的return值是如何决定排序操作顺序的? return 值在决定排序顺序时的意义是什么? Array.Sort() 的流程是如何发生的?
例如:
int[] ii = new int[3] { 8,1,4};
Array.Sort(ii, new myComp1());
有没有办法理解排序操作的流程。我的意思是如果我想决定一个特定的排序顺序,那么我应该如何写 if-else 条件或 return 值?
class myComp1 : IComparer<int>
{
public int Compare(int x, int y)
{
if (x == y)
return 1;
else if (x > y)
return -1;
else
return 0;
}
}
例如,在下面给出的代码中,我不明白比较器函数的 return 值的意义,无论它是按升序还是按降序或某种随机顺序。 MSDN没有解释的很清楚。
任何帮助。
我也想了解一下:下面代码中的Array.Sort()是不是先比较8和1,再比较1和4,再比较1和8?此执行是否有任何流程,以便作为程序员我可以在编写实际代码之前弄清楚它? 谢谢。
int[] kk = new int[3] { 8,1,4};
Array.Sort(kk, new myComp2());
class myComp2 : IComparer<int>
{
public int Compare(int x, int y)
{
int res = 0;
if (x == y)
return 1;
else if (x > y)
return 2;
else
return 3;
return res;
}
}
Array.Sort
或 .NET 中的任何其他 .Sort
变体按升序排序项目。
当你实现你的比较器时,结果的含义很简单:
- 小于 0:
x
小于y
- 大于 0:
x
大于y
- 等于 0:
x
等于y
- 比较操作必须是可传递的,例如1 ≤ 4 ≤ 8.
集合中项目的比较顺序取决于 sorting algorithm,因此无法保证 Compare
调用的特定顺序。
具有 IComparer<>
是一个很好的抽象,在其他场景中也很有用,而不仅仅是排序。
如果您想要任何特定的项目顺序,您可以定义保留传递性的比较器规则,或者可能不使用 .Sort
。
更新
作为程序员,你应该思考:
public int Compare(int x, int y)
{
// OPTION 1
if (x < y)
return -1; // X is less than Y, place X before Y - acsending order
...
// OPTION 2
if (x < y)
return 1; // X is less than Y, place X after Y - descending order
...
return 0; // keep order of X and Y if possible (stable comparison only)
}
更新 2
好的,假设我们有一个这样定义的比较器:
interface IComparer<T>
{
SortPlacement Compare(T x, T y);
}
其中SortPlacement
定义如下:
enum SortPlacement
{
Try_To_Keep_Same_Order_Of_X_and_Y = 0,
Place_X_Before_Y_Ascending_Order = -1, // or any negative number
Place_X_After_Y_Descending_Order = 1, // or any positive number
}
当你实现你的比较器时,你非常清楚:
public SortPlacement Compare(int x, int y)
{
// OPTION 1
if (x < y)
return SortPlacement.Place_X_Before_Y_Ascending_Order;
...
// OPTION 2
if (x < y)
return SortPlacement.Place_X_After_Y_Descending_Order;
...
// OPTION 3
return SortPlacement.Try_To_Keep_Same_Order_Of_X_and_Y;
}
现在忘记愚蠢的枚举类型并将其替换为整数 - 这是一个简单的约定。
排序算法使用 Compare
方法的 return 值来确定在对两个数字进行排序时,哪个数字应该排在另一个数字之前。
鉴于此签名:public int Compare(int x, int y)
return 值表示:
returnValue < 0
:x < y
returnValue == 0
:x == y
returnValue > 0
:x > y
所以如果方法 returns 0
,数字被认为是相等的(并且它们的顺序不会改变)。如果它 returns -1
,那么第一个数字应该 在 第二个数字之前。如果它 returns 1
,那么第一个数字应该在 第二个数字 之后。
现在,由于您已经更改了 Compare
方法中的定义,您将获得与通常预期不同的项目顺序,但这就是允许自定义比较器的全部意义所在 - 它留下关于 "which comes first" 的决定给你。
但是,由于 return 值实际上仅被评估为 0
、less than zero
或 greater than zero
,在您的第二个示例中,因为您总是 return 大于零的值,顺序将是未知的(这将取决于所使用的算法)。我这样说是因为当我用 {1, 5, 3}
测试它时它颠倒了它们,但是当我使用 {1, 5, 3, 4, 8}
时,顺序没有改变。
请注意,由于 comp2
return 中的所有案例的值都大于零,因此可以重写:
public int Compare(int x, int y) { return 1; }
另外,Array.Sort
的源代码在网上,如果你想看排序算法的使用,但你似乎更感兴趣什么