当找不到值时,C#List <t> .BinarySearch返回值</t>

时间:2010-08-15 09:10:58

标签: c# list generic-list

如果项目不存在,我对List<T>的BinarySearch方法感到困惑。

我有

List<long> theList = {1, 3, 5, ...}.

theList.BInarySearch(0)返回0,theList.BInarySearch(3)按预期返回1。

但是,theList.BinarySearch(1)会返回 -2 ,而不会像我期望的那样返回-1。 MSDN手册说: “返回值:已排序列表中项目的从零开始的索引,如果找到项目;否则,是负数,它是下一个元素的索引的按位补码,大于项目,或者,如果没有更大元素,Count的按位补码。“

“按位补码”?我在这里错过了什么,为什么theList.BinarySearch(1) != -1

4 个答案:

答案 0 :(得分:8)

我假设您在谈论theList.BinarySearch(2),因为1存在且返回值应为0

bitwise complement operator产生与否定整数相同的效果,我认为这是你混淆的根源。在任何情况下,您都不需要了解运算符如何准确地分支搜索结果;您问题中的MSDN段落以及~~a = a直接暗示此代码段的事实:

int index = theList.BinarySearch(num);

if (index >= 0)
{
    //exists
    ...
}
else
{
    // doesn't exist
    int indexOfBiggerNeighbour = ~index; //bitwise complement of the return value

    if (indexOfBiggerNeighbour == theList.Count)
    {
        // bigger than all elements
        ...
    }

    else if (indexOfBiggerNeighbour == 0)
    {
        // smaller than all elements
        ...
    }

    else
    {
        // Between 2 elements
        int indexOfSmallerNeighbour = indexOfBiggerNeighbour - 1;
        ...
    }
}

答案 1 :(得分:6)

首先 - 你为什么期望-1?如果该项目是第一个项目,则它不能返回-0(对于整数),因此第二个项目将返回原因-2。

接下来,您可以使用~-2 - 按位非运算符轻松获取正确的索引。

答案 2 :(得分:2)

返回这些否定索引的原因是支持将未找到的项插入到列表中。在此示例中,将在index = 2处插入2。否则,您将不得不执行另一个二进制搜索以找到该位置。

答案 3 :(得分:1)

要将其转换为插入点,请使用按位补码,即:~retval