算法:二分搜索:
问题解决:给定一个有 n 个元素的排序数组,编写一个函数来搜索数组中的给定元素 x。
一个简单的方法是做线性搜索。上述算法的时间复杂度是O(n)。
执行相同任务的另一种方法是使用二分搜索。
二分搜索:
通过重复将搜索间隔分成两半来搜索排序数组。
从覆盖整个数组的间隔开始。
如果搜索键的值小于区间中间的项,则将区间缩小到下半部分。
否则将其缩小到上半部分。反复检查,直到找到值或区间为空。
...
二分查找适用于已排序的数组。该值与数组的中间元素进行比较。
如果未找到相等,则消除其中不存在值的一半。
同理,搜索另一半部分。
二分查找的思想是利用数组排序的信息,将时间复杂度降低到O(Log n)。
我们基本上在一次比较之后就忽略了一半的元素:
- 将 x 与中间元素进行比较。
- 如果 x 与中间元素匹配,我们返回中间索引。
- Else 如果 x 大于中间元素,则 x 只能位于中间元素之后的右半子数组中。所以我们在右半边重复。
- Else(x 更小)在左半边重复出现。
public class BinarySearch
{
#region helpers.
/// <summary>
/// Returns index of x if it is present in int[], else return -1,
/// </summary>
/// <param name="array">array of sorted numbers</param>
/// <param name="l">start index</param>
/// <param name="r">end index</param>
/// <param name="x">searched number</param>
/// <returns>index of x</returns>
public static int Exist(int[] array, int l, int r, int x)
{
while (l <= r)
{
int med = (l + r) / 2;
// Check if x is present at mid
if (x == array[med])
return med;
// If x is smaller, ignore right half
if (x < array[med])
r = (med - 1);
// If x greater, ignore left half
else
l = (med + 1);
}
return -1;
}
/// <summary>
/// Returns index of first or last occurrence of a number if it is
present in int[], else return -1,
/// </summary>
/// <param name="array">array of sorted numbers</param>
/// <param name="l">start index</param>
/// <param name="r">end index</param>
/// <param name="x">searched number</param>
/// <param name="first">Boolean: true if searching first occurrence
or false if last</param>
/// <returns>index of x</returns>
public static int Exist(int[] array, int l, int r, int x, bool first)
{
int result = -1;
while (l <= r)
{
int med = (l + r) / 2;
// Check if x is present at mid
if (x == array[med])
{
result = med;
if (first)
r = (med - 1); //ignore right half
else
l = (med + 1); //ignore left half
}
else if (x < array[med])
r = (med - 1);
else
l = (med + 1);
}
return result;
}
#endregion
}
...
class Program
{
#region props.
public BinarySearch BinarySearch { get; set; }
#endregion
#region cst.
public Program()
{
this.BinarySearch = new BinarySearch();
}
#endregion
#region publics
public static void Main()
{
//int[] array = { 2, 3, 4, 10, 40 };
//int count = array.Length - 1;
//var result = BinarySearch.Exist(array, 0, count, 4);
int[] array = { 2, 10, 10, 10, 40 };
int count = array.Length - 1;
var result = BinarySearch.Exist(array, 0, count, 40, false);
Console.WriteLine(result == -1 ? "Element not present" :
$"Element
found at index {result}");
Console.ReadKey();
}
#endregion
}