浮法分类的比较方法

时间:2014-03-08 13:42:49

标签: c# list sorting comparison compareto

在我当前的项目中,我需要根据它们的位置对节点列表进行排序,该位置由两个浮点值表示。我在Node类中实现了IComparable接口,最初将其用作CompareTo方法:

public int CompareTo(Node other)
{
    if(y > other.y)
        return 1;
    else if(y < other.y)
        return -1;
    else if(x > other.x)
        return 1;
    else
        return -1;
}

然后我简单地调用了nodeList.Sort()。我们的想法是节点将按其Y排序,如果它们相等,则它们将按其X排序。 当我使用12个节点对其进行测试时,这很有效,但在将节点数增加到21之后,节点的顺序突然出现错误:

      x       y
 0: 2,089 | 0,048
 1: 1,195 | 0,145
 2: 2,603 | 0,499
 3: 1,750 | 0,750
 4: 0,478 | 0,526
 5: 2,620 | 1,942
 6: 2,868 | 1,473
 7: 2,806 | 0,960
 8: 2,071 | 2,146
 9: 1,452 | 2,119
 ...

我设法通过将CompareTo方法替换为:

来使其正常工作
public int CompareTo(Node other)
{
    int comparison = y.CompareTo(other.y);
    if (comparison != 0)
        return comparison;
    else
        return x.CompareTo(other.x);
}

现在它对包含12个节点的列表和具有21个节点的列表进行了正确排序。

使用它的另一个测试也给出了正确的结果:

public int CompareTo(Node other)
{
    int comparison = Math.Sign(y - other.y);
    if (comparison != 0)
        return comparison;
    else
        return Math.Sign(x - other.x);
}

我想知道的是为什么在添加更多节点后我的第一次尝试失败了?我做了一些关于浮点值比较的搜索,但是我发现在查看两个浮点数是否相等时可能会出错,这不是这里的情况(或者是吗?)。

我可以想象它与List.Sort()在列表具有> 16个元素时使用不同的算法这一事实有关,但我仍然不明白我的第一次尝试与float不同的原因。的CompareTo()?

1 个答案:

答案 0 :(得分:2)

你给出的原始排序函数没有正确处理相等的值,所以a.CompareTo(a)返回-1而不是预期的0.这不是CompareTo()的预期行为,它应该是传递的。 List.Sort()的内部实现可能依赖于此传递性,这将在您的实现中破坏。

如果您有兴趣进一步深入了解List.Sort()的内容,请查看ArraySortHelper的参考源,它由Array.Sort调用,由List调用。分类。看起来该算法依赖于.NET版本,并且还使用动态切换方法的IntroSort。