I am trying to search a descending sorted array using this binary search code. However, after I sort it, and try to search, it doesn't come back with any result, just a loading icon that never goes away as if it has an infinite loop. I'm not sure what the problem is because the code looks logical.
This is aspx with 4.0 framework, c#. Thanks in advance!
protected void Button2_Click(object sender, EventArgs e)
{
String item = TextBox1.Text;
int target = Convert.ToInt16(item);
int mid, first = 0, last = mynumbers.Length - 1;
//for a sorted array with descending values
while (first<=last)
{
mid = (first + last) / 2;
if (target < mynumbers[mid])
first = mid + 1;
if (target > mynumbers[mid])
last = mid - 1;
else
Label11.Text = "Target " + item + " was found at index " + mynumbers[mid];
}
There is a binary search in the Array
class:
int index = Array.BinarySearch(mynumbers, target);
For descending order, this can be easily accomplished with a ReverseComparer
which is easy to write like:
public class ReverseComparer<T> : IComparer<T>
{
public int Compare(T x, T y)
{
return Comparer<T>.Default.Compare(y, x);
}
}
Then:
int index = Array.BinarySearch(numbers, 7, new ReverseComparer<int>());
If this is an academic exercise and you must use a custom search, of course, this won't apply. If it's got to be a custom algorithm for a class, then the problems are that you must break out of the loop when found, and the index is at mid
, not at mynumbers[mid]
:
//for a sorted array with descending values
while (first<=last)
{
mid = (first + last) / 2;
if (target < mynumbers[mid])
{
first = mid + 1;
}
if (target > mynumbers[mid])
{
last = mid - 1;
}
else
{
// the index is mid, not mynumbers[mid], and you need to break here
// once found or it's an infinite loop once it finds it.
Label11.Text = "Target " + item + " was found at index " + mid;
break;
}
}
And actually, I'd probably set a bool flag instead to keep the algorithm pure and not mix the find with the output concerns, this will also make it easier to tell what happened if you exit the loop with not found:
bool found = false;
//for a sorted array with descending values
while (!found && first<=last)
{
mid = (first + last) / 2;
if (target < mynumbers[mid])
{
first = mid + 1;
}
if (target > mynumbers[mid])
{
last = mid - 1;
}
else
{
// You need to stop here once found or it's an infinite loop once it finds it.
found = true;
}
}
Label11.Text = found
? "Item " + item + " was found at position " + mid
: "Item " + item + " was not found";