二进制搜索的递归版本,可在数组中找到左边界

时间:2019-01-16 06:22:00

标签: c# arrays

美好的一天。 我坐在第二天,无法理解如何编写递归二进制搜索。 任务如下,找到左边框的索引。

https://imgur.com/a/jUwus0e 在各种条件下,需要对二进制搜索进行不同的修改。有四个选项:

  • 找到最后一个小于指定元素的元素(左边框)
  • 找到等于给定元素的第一个元素(第一个条目)
  • 找到等于给定元素的最后一个元素(最后一个条目)
  • 找到第一个大于指定元素(右侧)的元素

可以将左边界和右边界视为数组中应插入所需对象的位置,以免干扰排序。同时,右边框是在一系列相同对象的末尾处的插入位置,左边框是在一系列相同对象的末尾处的插入位置。

例如,通过搜索左右边界,可以计算值在给定范围[minValue,maxValue]中的数组中的元素数:

count = BinSearchRightBorder(arr, maxValue, -1, arr.Length) - BinSearchLeftBorder(arr, minValue, -1, arr.Length) - 1;

请注意,查找第一个匹配项的任务很容易简化为查找左边界的问题。同样,最后一次出现的次数减少到了右边界。

搜索边界时,可以合理地假设,如果零元素已经等于给定的元素,则左边界可以取值-1。如果最后一个元素等于指定的元素,则右边框可以采用array.Length的值。自然地,那么您需要使用left = -1和right = array.Length开始二进制搜索。

在此任务中,我需要添加二进制搜索的递归版本,该版本查找左边界,即找到较低值的最大元素的索引,如果表中没有必需的元素,则返回- 1;该代码必须是递归的。

同样,二分查找的含义是边界的逐渐移动,即[0,10]的间隔变为[0,5],然后变为[2,5],然后变为[4,5] ]然后元素[4]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BinarySearchApp
{
    class Program
    {
        static void Main(string[] args)
        {
            long[] arr = { -5, 1, 1, 2, 2, 2, 3, 6, 100};
            FindLeftBorder(arr, 2);

        }

        private static int FindLeftBorder(long[] arr, long value)
        {
            return BinSearchLeftBorder(arr, value, -1, arr.Length);
        }

        public static int BinSearchLeftBorder(long[] array, long value, int left, int right)
        {
            if (left == right)
            {
                if (array[left] == value) return left;
                return -1;
            }

            var m = (left + right) / 2;
            if (array[m] < value)
                return BinSearchLeftBorder(array, value, m, right - 1);
            return BinSearchLeftBorder(array, value, left, m);
        }
    }
}

可以帮我编写测试,以便在Visual Studio中找到错误吗? 我的代码有什么问题?欢迎任何评论!

我写了代码,但我只是想不出如何返回-1? 我还是C#的业余爱好者,所以我为这个问题的愚蠢表示歉意。 预先感谢大家的回答!

1 个答案:

答案 0 :(得分:0)

if(left == right - 1) return left;
var m = (left + right) / 2;
if (array[m] < value)
   return BinSearchLeftBorder(array, value, m, right);
return BinSearchLeftBorder(array, value, left, m);