Binary search explained:
A common problem is simply finding a specific item in a bunch of items. Binary search does this by cutting the "vision" in half until it finds an element, or find out that it does not exist. By checking the center of the current view, you can determine if the element is on the left or right, but for this the elements must be sorted.
An example in theory (an element exists):
Suppose we were looking for 1 in this array of elements:
0, 1, 4, 4, 6, 7, 9, 10
At every step, we mark our field of vision, and it looks like this:
- S = beginning of field of view
- E = end of field field
- M = average field of view = (S + E + 1) / 2
SME 0, 1, 4, 4, 6, 7, 9, 10
The value in M is 6, which is more than 1, so we know that 1 is on M on the left. Therefore, we set E as M-1 and recount M:
SME 0, 1, 4, 4, 6, 7, 9, 10
The value in M is now 4 - even more than 1, so we go further:
M SE 0, 1, 4, 4, 6, 7, 9, 10
The value in M is now 1, this is the value we were looking for, so we are done!
An example in theory (an element does not exist):
Suppose we were looking for 5 in this array of elements:
0, 1, 4, 4, 6, 7, 9, 10
At every step, we mark our field of vision, and it looks like this:
- S = beginning of field of view
- E = end of field field
- M = average field of view = (S + E + 1) / 2
SME 0, 1, 4, 4, 6, 7, 9, 10
The value in M is 6, which is more than 5, so we know that 5 is on M on the left. Therefore, we set E as M-1 and recount M:
SME 0, 1, 4, 4, 6, 7, 9, 10
The value in M is now 4, which is less than 5, so we know that 5 must be on M on the right. Therefore, we set S as M + 1 and recount M:
S E M 0, 1, 4, 4, 6, 7, 9, 10
The value in M is now 4, which is less than 5, so we must go further to the right, but oops! S = E means that if we move on, they will cross each other, that is, we already looked there, so the element, of course, does not exist, and the search ends.
Pseudo-code + explanations:
arr = 0, 1, 4, 4, 6, 7, 9, 10; wanted = 5; // Holds the value to look for index = -1; // Will hold the index of the found value (-1 means not found) s = 0; // Initialize S with the beginning of all array e = arr.Length - 1; // Initialize E with the last element of the array // As long as we don't cross ourselves while (s <= e) { // Calculate M (rounded) m = (s + e + 1) / 2; // Get the current middle value curr = arr[m]; // Check to see if we found our wanted value if (curr == wanted) { index = m; break; } else if (curr < wanted) { // Wanted value is further to the right s = m + 1; } else { // Wanted value is further to the left e = m - 1; } } // Here, if index is -1, the wanted value does not exist in arr. // Otherwise, it holds it index.
Common C # code:
public int BinarySearch<T>(this ICollection<T> elements, T item) where T : IComparable { // Assumes that elements is already sorted! var s = 0; var e = elements.Count - 1; while (s <= e) { var m = (s + e + 1) / 2; var cmp = elements[m].CompareTo(item); switch (cmp) { case -1: s = m + 1; break; case 1: e = m - 1; break; default: return m; } } return -1; }
Application:
int[] nums = ...; List<double> doubles = ...; SortedSet<People> people = ...;