如何跟踪二进制搜索算法中的最后一个索引?

时间:2019-01-08 04:01:52

标签: c binary-search

我正在解决一种简单的二进制搜索算法,但无法跟踪问题中的最后一个索引。

尽管,我尝试并包括了一个计数器,但由于没有给我期望的输出而徒劳,

  void binarySearch(int Arr[], int Size, int Search)
   {
    int Flag=0, Counter=1, First=0, Last=Size-1, Mid;
   while(First<=Last)
      {
       Mid=(First+Last)/2;
       printf("\nGuess %d (half of %d to %d) -> ", Arr[Mid], First, 
             (Last+Counter));
           if(Arr[Mid]==Search)
              {
                  printf("spot on!");
                  Flag=1;
                   break;
             }
           else if(Arr[Mid]<Search)
             {
                printf("you're too low.");
                First=Mid+1;
             }
           else
             {
                 ++Counter;
                 printf("you're too high.");
                 Last=Mid-1;
             }
      }
   if(Flag==0)
      printf("\nElement Not Found!!");
 printf("\n");
}

预期输出:-

说我选择的电话号码是38。您打算做什么?进行二进制搜索:

猜50(从0到100的一半)→您太高了。

猜25(0至50的一半)→你太低了。

猜猜37(25至50的一半)→你太低了。

猜猜43(37至50的一半)→你太高了。

猜40(从37到43的一半)→你太高了。

猜猜38(37至40的一半)→当场!

实际输出:-

猜50(0至100的一半)->你太高了。

猜25(0至50的一半)->你太低了。

猜猜37(25至50的一半)->你太低了。

猜猜43(37至50的一半)->你太高了。

//这是我的疑问

猜40(从37到44的一半)->你太高了。

猜猜38(37至42的一半)->当场!

1 个答案:

答案 0 :(得分:3)

有效的二进制搜索的诀窍是您首先检查数组中的第一个和最后一个元素。

很显然,如果您搜索的值在外部,则无需执行二进制搜索;如果两端都匹配,您就找到了。

但是,这意味着二进制搜索的边界是排他性的。在计算下一个要探查的元素的索引时,如果它与边界之一匹配,则说明没有匹配项。

在伪代码中,这意味着我们可以编写二进制搜索,假设排序的数组中值的值递增,并像C中一样从0开始索引,如下所示:

Function BinarySearch(array[], length, value):

    If (length < 1):
        # Empty array.
        Return NotFound
    End If

    If (value < array[0]):
        # Value is smaller than those in the array.
        Return NotFound
    Else If (value == array[0]):
        Return Found at index 0
    End If

    If (value > array[length - 1]):
        # Value is greater than those in the array.
        Return NotFound
    Else If (value == array[length - 1]):
        Return Found at index length - 1
    End If

    Let  iMin = 0
    Let  iMax = length - 1
    Loop:

        Let  i = (iMin + iMax) / 2   # Integer division, rounds towards zero
        If (i == iMin):
            Return NotFound
        End If

        If (array[i] < value):
            iMin = i
        Else If (array[i] > value):
            iMax = i
        Else:
            Return Found at index i
        End If
    End Loop
End Function

使用整数除法,并且iMiniMax为非负数(正数或零)时,i = (iMin + iMax)/2会四舍五入到零,而i == iMin首先出现,所以我们这样做无需显式检查i == iMax。 (也就是说,i == iMax在这种情况下也仅在i == iMin时出现,因此没有必要进行检查。)

在循环中,当我们更新iMiniMax时,我们已经分别检查过array[iMin]array[iMax]iMin是指索引值比我们要寻找的索引小的索引,iMax是指索引值比我们要寻找的索引的索引更大。因此,我们基本上只考虑索引大于 iMin但小于 iMax的数组元素;排除索引iMiniMax