繁体   English   中英

C# 递归二分查找

[英]C# Recursive Binary Search

我正在尝试为此List<int>实现递归二进制搜索

List<int> primes = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

Console.WriteLine(RecursiveBinarySearch.FindNumber(primes, 9));
Console.WriteLine(RecursiveBinarySearch.FindNumber(primes, 12));

这是我的递归二进制搜索

public static class RecursiveBinarySearch
    {
        public static bool FindNumber(List<int> setOfNumbers, int targetNumber)
        {
            if (setOfNumbers.Count == 0)
            {
                return false;
            }

            int midpoint = setOfNumbers.Count / 2;

            if (setOfNumbers[midpoint] == targetNumber)
            {
                return true;
            }
                
                
            if (setOfNumbers[midpoint] < targetNumber)
            {
                setOfNumbers.RemoveRange(setOfNumbers[0], midpoint);
                return FindNumber(setOfNumbers, targetNumber);
            }
            else
            {
                setOfNumbers.RemoveRange(setOfNumbers[midpoint + 1], setOfNumbers.Count - 1);
                return FindNumber(setOfNumbers, targetNumber);
            }
        }
    }

我越来越

参数异常
index 和 count 不表示列表中元素的有效范围

在这一行:

if (setOfNumbers[midpoint] < targetNumber)
            {
                setOfNumbers.RemoveRange(setOfNumbers[0], midpoint);
                return FindNumber(setOfNumbers, targetNumber);
            }

这是我在 Visual Studio 中的变量值的屏幕截图。 https://snipboard.io/iQ6ZIc.jpg

如果您运行了代码或查看了屏幕截图,您会看到midpoint2 ,因此RemoveRange()的 arguments 都是有效的并且在范围内,这就是我不明白它抛出异常的原因。

我错过了什么?

您可能不想实现通过删除项目来工作的搜索方法。 这可能比仅仅进行线性搜索要慢得多。 它还修改了原始集合,这通常不是您对名为FindNumber的方法所期望的。 您可能希望使用一种将指定范围作为参数进行搜索的方法。 例如:

public static bool FindNumber(List<int> setOfNumbers, int targetNumber)
    => FindNumber(setOfNumbers, targetNumber, 0, targetNumber.Count);

private static bool FindNumber(List<int> setOfNumbers, int targetNumber, int startIndex, int count){

    int midpoint = startIndex + count / 2;
    var endIndex = startIndex + count;

   ...
    // Search lower range
    return FindNumber(setOfNumbers, targetNumber, startIndex, midpoint  - startIndex);
   ...
   // Search upper range
   return FindNumber(setOfNumbers, targetNumber, midpoint , endIndex - midpoint );
}

您还可以考虑返回找到的数字的索引,或者只使用BinarySearch的现有实现。

您还可以考虑将输入类型更改为IReadOnlyList<int>Span<int>以接受任何类型的顺序列表,并接受带有IComparer<T>参数的泛型类型以进行比较,使用Comparer<T>.Default作为默认值,如果没有使用显式比较器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM