Last active
February 4, 2019 16:25
-
-
Save CallumWatkins/02bd44a624a0d370650488ffb1042382 to your computer and use it in GitHub Desktop.
Two binary search implementations using ReadOnlySpan<T>. One returns the index of the item, the other returns a Boolean. License: MIT
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Searches an entire one-dimensional sorted span for a value using the specified comparer. | |
/// </summary> | |
/// <typeparam name="T">The type of the items being searched.</typeparam> | |
/// <param name="span">The sorted span to search.</param> | |
/// <param name="item">The item to search for.</param> | |
/// <param name="comparer">The comparer implementation to use when comparing elements.</param> | |
/// <returns>True if the item is in the input; false otherwise.</returns> | |
/// <exception cref="ArgumentNullException">Thrown when <paramref name="comparer"/> is null.</exception> | |
static bool BinarySearch<T>(ReadOnlySpan<T> span, T item, IComparer<T> comparer) | |
{ | |
if (comparer == null) throw new ArgumentNullException(nameof(comparer)); | |
while (span.Length > 0) | |
{ | |
int i = span.Length / 2; | |
int comparison = comparer.Compare(item, span[i]); | |
if (comparison < 0) span = span.Slice(0, i); | |
else if (comparison > 0) span = span.Slice(i + 1); | |
else return true; | |
} | |
return false; | |
} | |
/// <summary> | |
/// Searches an entire one-dimensional sorted span for a value using the specified comparer. | |
/// </summary> | |
/// <typeparam name="T">The type of the items being searched.</typeparam> | |
/// <param name="span">The sorted span to search.</param> | |
/// <param name="item">The item to search for.</param> | |
/// <param name="comparer">The comparer implementation to use when comparing elements.</param> | |
/// <returns>The index of the item if found; -1 otherwise.</returns> | |
/// <exception cref="ArgumentNullException">Thrown when <paramref name="comparer"/> is null.</exception> | |
static int BinarySearch<T>(ReadOnlySpan<T> span, T item, IComparer<T> comparer) | |
{ | |
if (comparer == null) { throw new ArgumentNullException(nameof(comparer)); } | |
int position = 0; | |
while (span.Length > 0) | |
{ | |
int i = span.Length / 2; | |
int comparison = comparer.Compare(item, span[i]); | |
if (comparison < 0) { span = span.Slice(0, i); } | |
else if (comparison > 0) | |
{ | |
span = span.Slice(i + 1); | |
position += i + 1; | |
} | |
else { return position + i; } | |
} | |
return -1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment