forked from TheAlgorithms/C-Sharp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
RecursiveBinarySearcher.cs
65 lines (59 loc) · 2.48 KB
/
RecursiveBinarySearcher.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
using System;
using System.Collections.Generic;
namespace Algorithms.Search
{
/// <summary>
/// RecursiveBinarySearcher.
/// </summary>
/// <typeparam name="T">Type of searcher target.</typeparam>
public class RecursiveBinarySearcher<T> where T : IComparable<T>
{
/// <summary>
/// Finds index of item in collection that equals to item searched for,
/// time complexity: O(log(n)),
/// space complexity: O(1),
/// where n - collection size.
/// </summary>
/// <param name="collection">Sorted collection to search in.</param>
/// <param name="item">Item to search for.</param>
/// <exception cref="ArgumentNullException">Thrown if input collection is null.</exception>
/// <returns>Index of item that equals to item searched for or -1 if none found.</returns>
public int FindIndex(IList<T>? collection, T item)
{
if (collection is null)
{
throw new ArgumentNullException(nameof(collection));
}
var leftIndex = 0;
var rightIndex = collection.Count - 1;
return FindIndex(collection, item, leftIndex, rightIndex);
}
/// <summary>
/// Finds index of item in array that equals to item searched for,
/// time complexity: O(log(n)),
/// space complexity: O(1),
/// where n - array size.
/// </summary>
/// <param name="collection">Sorted array to search in.</param>
/// <param name="item">Item to search for.</param>
/// <param name="leftIndex">Minimum search range.</param>
/// <param name="rightIndex">Maximum search range.</param>
/// <returns>Index of item that equals to item searched for or -1 if none found.</returns>
private int FindIndex(IList<T> collection, T item, int leftIndex, int rightIndex)
{
if (leftIndex > rightIndex)
{
return -1;
}
var middleIndex = leftIndex + (rightIndex - leftIndex) / 2;
var result = item.CompareTo(collection[middleIndex]);
return result switch
{
var r when r == 0 => middleIndex,
var r when r > 0 => FindIndex(collection, item, middleIndex + 1, rightIndex),
var r when r < 0 => FindIndex(collection, item, leftIndex, middleIndex - 1),
_ => -1,
};
}
}
}