二分查找又称折半查找,它是一种效率较高的查找方法。
特点:
1、二分查找仅适合线性表的顺序存储结构,不适合链式存储结构。
2、必须按关键字大小有序排列
原理:
①、将数组分为两半,并且算出中间的下标mid,前一半从下标0到mid - 1,后一半从mid + 1到数组最后一个元素。
②、将要查找的数与数组下标为mid的元素进行比较,如果要查找的数大,则把查找范围缩小到原数组的后一半(反之放到前一半),重新确定下标mid和初始点(或者终点)。
③、重复②过程,直到找到要查找的元素。
代码:
/// <summary>
/// 使用递归排序进行二分查找
/// </summary>
/// <param name="arr">待查询数组</param>
/// <param name="start">开始索引</param>
/// <param name="end">结束索引</param>
/// <param name="target">查询目标</param>
/// <returns></returns>
public static int Sort(int[] arr, int start, int end, int target)
{
int mid = (start + end) / 2; //中间索引
//没有找到返回-1
if (start > end)
{
return -1;
}
else
{
if (arr[mid] < target)
{
return Sort(arr, mid + 1, end, target);
}
else if (target < arr[mid])
{
return Sort(arr, 0, mid - 1, target);
}
else
{
return mid;
}
}
}
/// <summary>
/// 使用While循环实现二分查找
/// </summary>
/// <param name="arr">待查询数组</param>
/// <param name="start">开始索引</param>
/// <param name="end">结束索引</param>
/// <param name="target">查询目标</param>
/// <returns></returns>
public static int Sort2(int[] arr, int start, int end, int target)
{
while (start <= end)
{
int mid = (start + end) / 2;
if (arr[mid] < target)
{
start = mid + 1;
}
else if (arr[mid] > target)
{
end = mid - 1;
}
else
{
return mid;
}
}
return -1;
}
时间复杂度:
最优时间复杂度是,在第一次查找就找到了,为O(1);
最坏情况下,二分查找在最后一次才能查找到关键字,因为每次都在所有元素的一=半进行查找,所以最坏时间复杂度为:O(logn);