[英]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
如果您运行了代码或查看了屏幕截图,您会看到midpoint
为2
,因此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.