二分查找法浅析

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

 
原文地址:https://www.cnblogs.com/davidshi/p/3340628.html