排序()和的CompareTo的内部工作()方法(Internal working of the S

2019-07-21 01:43发布

我一直在试图找出如何CompareTo()方法的内部工作,我失败了。 我搜索这个网站,看了一些帖子,我想我已经看到了有在MSDN看到关于这个问题,我只是似乎没有得到它。 一个MSDN例子:

public int CompareTo(object obj)
{
    if (obj == null)
    {
        return 1;
    }

    Temperature otherTemperature = obj as Temperature;
    if (otherTemperature != null)
    {
        return this.temperatureC.CompareTo(otherTemperature.temperatureC);
    }
    else
    {
        throw new ArgumentException("the object is not a temperature");
    }
}

这是执行的MSDN示例CompareTo()方法。 我明白这一点,我明白了如何IComparable接口工作,如果我理解正确的,当我使用这个被调用ArrayList.Sort()方法。

我不明白的是:什么时候该计划通过对参数CompareTo(object obj)的方法? 或者换句话说,请问该怎么Sort()方法的工作? 我的意思是,这个代码是一个温度的情况下随温度的另一个实例比较,但何时或如何将节目获得第二温度实例对比发生? 我希望我的问题是有道理的。

我试着打印到屏幕上CompareTo()过程,所以也许我可以反向工程的输出,但我感到很困惑,甚至更多。

编辑 :也许,如果我走一步看一步,我可以更好地解释自己。 假设我有3点温度的对象:34,45,21中的ArrayList 。 当我打电话ArrayList.Sort()CompareTo()称为像法34.CompareTo(45) 然后45.CompareTo(21) 返回的整数是1的第一比较和第二-1? 又是如何的整数得到恢复,如果我只定义CompareTo()方法返回1只有在OBJ(参数)为空? 我没有定义什么返回-1或0。就好像我正在实施包括已经实现的方法。 限定CompareTo()时,它的已定义为返回-1,0和1的方法。

Answer 1:

让我们先从基本概念。

什么是的CompareTo的目的是什么?

什么是42到1337年是42 ... 大于小于等于 1337?

这个问题和答案其由建模CompareTo在方法IComparable<T>IComparable接口。 对于A.CompareTo(B)该方法可以返回:

  • A是大于 B:一个整数值大于0。
  • A 小于 B:小于0的整数值。
  • A 等于 B:一个整数值等于0。

当然还有, IComparable不限于整数。 您可以实现IComparable到,你认为应该是可比的任何两个比较对象。 例如,字符串:

什么是“犰狳”到“梦幻西游”:是“犰狳” ... 大于小于等于 “十二生肖”?

答案取决于你的大于,小于和等于定义。 对于字符串通常的顺序是,这将在以后的字典发生的一句话就是之前就已发生更大的词。

如何帮助的CompareTo排序?

好了,现在你知道你可以比较任意两个对象。 这是很多算法是有用的,但主要是分类和排序算法。 举例来说,一种非常简单的排序算法: 愚蠢的排序 。 我们的想法是:

看看在你的阵列,A和B两个相邻的元素
当A <= B:前进到下一对。
当A> B:交换A和B,并返回到以前的对。
当我们到达终点,我们就大功告成了。

你看,得到整理,必须有一种方法来确定两个元素是更大的一个。 这就是IComparable<T>的用武之地。

public static void StupidSort<T>(T[] array)
            where T : IComparable<T>
{
    int index = 0;
    while (index < array.Length)
    {
        if (index == 0 ||
            array[index - 1].CompareTo(array[index]) <= 0)
        {
            index++;
        }
        else
        {
            Swap(array, index - 1, index);
            index--;
        }
    }
}

当的CompareTo将始终返回1,会发生什么?

当然程序可以CompareTo返回你想要的任何东西。 但是,如果你搞砸了,那么你的方法不再回答的问题是什么thisobj 总是返回一个1是指对于任何A和B,A总是大于B.这就像说:20大于10 10大于20,这没有意义,其结果是,任何你排序这样做也没有任何意义。 垃圾进垃圾出。

游戏的规则是,对于给定的3个对象A,B和C:

  • A.CompareTo(A)必须返回0(A等于A)。
  • 如果A.CompareTo(B)返回0,然后B.CompareTo(A)返回0( 如果A等于B,则B等于A)。
  • 如果A.CompareTo(B)返回0,和B.CompareTo(C)返回0,然后A.CompareTo(C)返回0( 如果A等于B,和B等于C,则A是等于C )。
  • 如果A.CompareTo(B)返回一个值大于0,则B.CompareTo(A)返回一个小于0的值( 如果A大于B,则B是小于A)。
  • 如果A.CompareTo(B)返回小于0的值,则B.CompareTo(A)返回一个大于0的值( 如果A小于B,则B是大于A)。
  • 如果A.CompareTo(B)返回一个值大于0,和B.CompareTo(C)返回一个大于0的值,然后A.CompareTo(C)返回一个大于0的值( 如果A大于B,和B是大于C,则A是大于C)。
  • 如果A.CompareTo(B)返回小于0的值,并且B.CompareTo(C)返回一个值小于0,则A.CompareTo(C)返回一个小于0的值( 如果A小于B,和B小于C,则A是小于C)。
  • null总是比任何非空的对象较少。

如果您的实施不遵守这些(简单的和逻辑的)原则,然后排序算法可以从字面上做任何事情,而且很可能不给你所期望的结果。



Answer 2:

如果要比较ab ,你说:

int result=a.CompareTo(b);

即,第一比较操作数是this ,第二个是传递给函数的参数。

然后,当你排序的阵列,无论算法的使用,你必须比较元素结合在一起,把他们作为thisobjobject.CompareTo (或该函数的重载可行)。



Answer 3:

排序方法是独立于的CompareTo方法。 我不知道是干什么用的排序算法,但我猜这件事情就像一个快速排序(OBV不冒泡排序)。 如果你有兴趣在这些算法维基百科记载加以详细。

所述CompareTo方法是简单地比较相同类型的对象的装置。 它定义了许多常见的.NET类型的开始与和可重写做(事您创建)的自定义对象之间的比较。 基本上你从类型的对象A传递给它类型A​​的第二对象,并且返回值调用它表示如果两者相等,或者如果一个比另一个大。

这是最好想CompareTo的效用函数。 它的存在,所以你能做的使用提供与普通.NET数据结构的排序方法的自定义比较。 如果没有类似的东西,你会写自己的排序算法,以比较您所创建的类型。 它的目的仅仅是使排序方法为可重复使用的/可扩展的。



Answer 4:

总之,排序需要你的ArrayList的两个元素,并为第一要素调用的CompareTo,并通过第二个元素作为参数,如下所示:

element1.CompareTo(element2)

如果元素1是在element2以下,0,如果它们相等,正否则值的CompareTo返回负值。 排序使用此返回值,嗯,做一些整理。 然后重复这个过程,后面两个要素,做多一些排序,依此类推,直到ArrayList的排序。 搜索“排序算法”,以获取有关这一过程的详细信息。



Answer 5:

有不同的排序算法。 但是,不管是什么有时候会有这样的算法必须决定哪些元素是较大的,这是当点CompareTo被调用。

a.CompareTo(b) < 0;

如果a和b是Integers (或伪),你也可以使用:

a < b

我想你会发现a < b在大量的伪代码或整数排序算法的例子符号。 CompareTo的方法IComparable<T>是一个面向对象的实现-或符号。



文章来源: Internal working of the Sort() and CompareTo() methods