二分法查找
今天講一下「二分法查找」,二分法查找思路就是在一段順序數組中,每次和某一段數組中間數比大小。二分法查找的缺點是數組必須是順序的(我以由小到大排序數據爲例),優勢是查詢效率極高,時間複雜度是log2n。這種查找方式越是在大數據下,效果越是明顯。下面附上源代碼和單元測試,源代碼包含兩種算法,一種是循環一種是遞歸,你們多參考:
源代碼:算法
/// <summary>
/// 使用二分法查找一個數據所在問題位置。(遞歸方法)
/// 數組必須是從小到大排序的,若是是未排序數據可以使用<see cref="BitmapSort"/>類
/// 或者<see cref="StraightInsertionSort"/>類進行排序。
/// 若是要查找的值在數組中不存在,返回-1。
/// </summary>
/// <param name="array">數組</param>
/// <param name="value">要查找的值</param>
/// <returns>返回第幾個,若是要查找的值在數組中不存在,返回-1</returns>
public static int Search(int[] array, int value)
{
if (array == null) { throw new ArgumentException("array is null"); }
if (array[array.Length - 1] == value) { return array.Length - 1; }
return Search(array, 0, array.Length - 1, value);
}
private static int Search(int[] array, int beginIndex, int endIndex, int value)
{
int middle = (beginIndex + endIndex) / 2;
if (endIndex == beginIndex)
{ return array[beginIndex] == value ? beginIndex : -1; }
else if (endIndex == beginIndex + 1)
{
if (array[beginIndex] == value) { return beginIndex; }
else if (array[endIndex] == value) { return beginIndex; }
else { return -1; }
}
if (array[middle] == value)
{ return middle; }
else if (array[middle] > value)
{ return Search(array, beginIndex, middle, value); }
else if (array[middle] < value)
{ return Search(array, middle, endIndex, value); }
return -1;
}
/// <summary>
/// 使用二分法查找一個數據所在問題位置。(循環方法)
/// 數組必須是從小到大排序的,若是是未排序數據可以使用<see cref="BitmapSort"/>類
/// 或者<see cref="StraightInsertionSort"/>類進行排序。
/// 若是要查找的值在數組中不存在,返回-1。
/// </summary>
/// <param name="array">數組</param>
/// <param name="value">要查找的值</param>
/// <returns>返回第幾個,若是要查找的值在數組中不存在,返回-1</returns>
public static int Search2(int[] array, int value)
{
int beginIndex = 0;
int endIndex = array.Length - 1;
while (true)
{
if (endIndex - beginIndex <= 1)
{
if (value == array[beginIndex]) { return beginIndex; }
if (value == array[endIndex]) { return endIndex; }
{ return -1; }
}
int middle = (beginIndex + endIndex) / 2;
if (value < array[middle]) { endIndex = middle; }
if (value == array[middle]) { return middle; }
if (value > array[middle]) { beginIndex = middle; }
}
}數組
單元測試:
[TestMethod()]
[DeploymentItem("ZjyWorkCodeLibrary.dll")]
public void SearchTest()
{
Random random = new Random();
int[] array2 = new int[100];
for (int i = 0; i < 100; i++)
{
array2[i] = random.Next(0, 1000);
}
int[] array3 = BitmapSort.Sort(array2);
for (int i = 0; i < array3.Length; i++)
{
Assert.AreEqual(BinarySearch.Search(array3, array3[i]), i);
Assert.AreEqual(BinarySearch.Search2(array3, array3[i]), i);
}
Assert.AreEqual(BinarySearch.Search(array3, 9999), -1);
Assert.AreEqual(BinarySearch.Search2(array3, 9999), -1);
}dom