C#List.Sort没有排序

时间:2014-09-25 21:28:32

标签: c# sorting

我想要排序List<T>,所以我使用了List<T>.Sort(Comparison<T>)。我的代码没有按预期工作,经过一些调试我发现虽然包含在内的项目的顺序确实发生了变化,但它并没有被排序。
代码在这里:

System.Comparison<Intersection> comp=(Intersection one, Intersection other)=>{//Sort sorts from lowest to highest
    if(one.index>other.index){
        return 1;
    }
    else if(one.index<other.index){
        return -1;
    }
    else if((one.point-one.node.position).sqrMagnitude>(other.point-other.node.position).sqrMagnitude){
        return 1;
    }
    else{
        return -1;
    }
};
intersections.Sort(comp);

麻烦的是,在排序之后,可以按顺序找到项目,使得第三项具有索引7而第四项具有6.我认为比较lambda可能有问题,但我添加了一个使用的代码相同的功能来比较顺序项目,但它表现正确,有时返回1,所以问题显然在其他地方 后来的比较:

for(int he=1; he<intersections.Count; he++){
    Debug.Log(comp(intersections[he-1], intersections[he]));
}

是否有我遗漏的内容或我的List<T>.Sort实施错误,我应该制作自己的排序方法?

结构如下:

class Intersection{
    public PolyNode node;
    public int index;
    public Polygon poly;
    public Intersection sister;
    public bool is_out;
    public sbyte wallnum;
    public Vector2 point;
    public int list_index;
}

2 个答案:

答案 0 :(得分:12)

要扩展500内部服务器错误(正确)答案,Quicksort需要一个良好的比较功能。您必需提供以下对比:

  • 具有反身性:项目必须比较等于自身
  • 在不平等中是反对称的:如果A大于B,那么B 必须也小于A
  • 是相等对称的:如果A等于B,那么B 必须也等于A
  • 具有传递性:如果A等于B且B等于C,则A 必须等于C.如果A大于B且B大于C,则A <强>必须大于C.依此类推

简而言之,必须提供 total ordering relation 。您的比较算法违反了许多这些要求。只要您未能提供总订购关系,就会发生不好的事情。算法可能会崩溃,它可以进入无限循环,或者它可以返回未排序的列表。

有关较长时间的讨论,请参阅我编写的关于我所看到的错误比较算法的常见方法的四部分系列文章:

http://ericlippert.com/2011/01/20/bad-comparisons-part-one/

答案 1 :(得分:5)

正如其他人也指出的那样,你的比较函数永远不会返回零(相等)的结果,但List.Sort依赖于比较函数在项目与自身进行比较时返回相等。