二分查找法浅析
题目:编一二分法递归查找函数 BinSearch(a(),low, high,n,key) 对递减有序数组a中查找key值,查找到返回数组的下标,找不到返回-1。
思路:1: 如果待查找的元素比数组中间的元素小 ,那么(此时递归)调用该方法本身的时候,新的“数组”的界限就变成了从low到mid-1 ,也就是“左半端”,然后一直找下去一直到找到了或者是low》high了(没招到,返回-1),方法体结束。 2 同理是右半段。 3就是恰好找到了,此时返回mid,该方法体结束。 时间复杂度O(2log2(n));
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BinarySearch
{
class Program
{
static void Main(string[] args)
{
int[] arr = new int[] { 3, 32, 42, 124, 235, 42452, 2358954 };
Program p = new Program();
int b = p.BinarySearch(arr,3,0,arr.Length-1);
Console.WriteLine(b);
Console.ReadKey();
}
private int BinarySearch(int[] arr, int key, int low, int high)
{
//int temp = 0;
if (low > high || high < 0)
{
return -1;
}
int mid=(low+high)/2;
if (key < arr[mid])
{
return BinarySearch(arr,key,low,mid-1);
}
else if (key > arr[mid])
{
return BinarySearch(arr, key, mid + 1, high);
}
else
{
return mid;
}
}
}
}
二分算法是比较基础的算法,但在用c#写的程序中用到的很少,因为对于链表很多情况下就用LIst来实现了,数组用的也不是很多。这里粗浅的记录一下c#对二分的实现。
题目:在一个已经排序的数组中查找给定数值的索引,如果未找到,则返回-1.
///
/// 使用二分查找给定数值在数组中的索引,数组应是一个已经排序的数组
///
/// 查找的数组
/// 要查找的数组
/// 索引
private static int FindNumber ( int [ ] array, int value )
{
Stopwatch watch = new Stopwatch ( );
watch.Start ( );
int index = -1;
int lowIndex = 0;
int highIndex = array.Length - 1;
int middleIndex = -1;
while ( lowIndex <= highIndex )
{
middleIndex = ( lowIndex + highIndex ) / 2;
if ( value == array [ middleIndex ] )
{
index = middleIndex;
break;
}
if ( value > middleIndex )
lowIndex = middleIndex + 1;
else
highIndex = middleIndex - 1;
}
watch.Stop ( );
Debug.WriteLine ( string.Format ( "{0}ms" , watch.ElapsedMilliseconds ) );
return index;
}
进一步延伸一下,对于int、float等都是值类型的对象,因此可以考虑使用泛型来处理,对于引用类型的对象那对如何处理呢?这里可以考虑使用IComparable接口来进行约束。因此二分查找的泛型版本可以用如下表示。
///
/// 二分查找索引
///
/// 查找的对象,必须实现IComparable接口
/// 对象数组
/// 要查找的值
/// 找到的索引
public static int FindIndex ( T [ ] array, T value ) where T : IComparable
{
Stopwatch watch = new Stopwatch ( );
watch.Start ( );
int index = -1;
int lowIndex = 0;
int highIndex = array.Length - 1;
int middleIndex = -1;
while ( lowIndex <= highIndex )
{
middleIndex = ( lowIndex + highIndex ) / 2;
if ( value.CompareTo ( array [ middleIndex ] ) == 0 )
{
index = middleIndex;
break;
}
if ( value.CompareTo ( middleIndex ) > 0 )
lowIndex = middleIndex + 1;
else
highIndex = middleIndex - 1;
}
watch.Stop ( );
Debug.WriteLine ( string.Format ( "{0}ms", watch.ElapsedMilliseconds ) );
return index;
}
三分查找算法,时间复杂度O(3log3(n)):
static bool Find(int[] sortedArray, int number)
{
if (sortedArray.Length == 0)
return false;
int start = 0;
int end = sortedArray.Length - 1;
while (end >= start)
{
int firstMiddle = (end - start) / 3 + start;
int secondMiddle = end - (end - start) / 3;
if (sortedArray[firstMiddle] > number)
end = firstMiddle - 1;
else if (sortedArray[secondMiddle] < number)
start = secondMiddle + 1;
else if (sortedArray[firstMiddle] != number && sortedArray[secondMiddle] != number)
{
end = secondMiddle - 1;
start = firstMiddle + 1;
}
else
return true;
}
return false;
}