题目:编一二分法递归查找函数 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;
}