• 二分查找法浅析


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

     
  • 相关阅读:
    mybatis新增insert返回主键id,与解决新增主键id一直为1的问题。
    Mysql SQL语句查询今天、昨天、N天内、第N天的数据
    记录实时问题:java 出现unreachable statement异常
    java代码读取properties配置文件实例
    java设计模式详解
    java自用代码(包括:新建单线程、创建文件夹及文件、map转为json并将json写入txt、文件剪切或改名)
    ssm框架之持久层mybatis动态sql标签属性大全
    从onclick到function到ajax的url问号传多个参数(更多的话以此类推)问题
    TortoiseGit右击不显示图标或不显示状态图标等处理方法(win10、win7)
    Delphi 在写Ini文件时报错,Access violation at address 774D6EC8 in module 'ntdll.dll' write of address 004044CD
  • 原文地址:https://www.cnblogs.com/davidshi/p/3340628.html
Copyright © 2020-2023  润新知