通用二分查找算法

前注:

这是自己平时写的一些小代码,未必有用及符合设计原则,若有不妥之处,还请大家指教。

说明:

此算法与另一个通用快速排序算法采用了相似的设计思想:对排序和查找算法而言,虽然其逻辑固定,但由于数据源与比较或搜索逻辑的差异,而数据处理的过程又与算法逻辑相藕合,因而不得不对不同的数据源及比较逻辑作不同的实现。也因此,若要抽象出算法逻辑,则必须提取数据操作与比较接口。

对二分查找算法而言,可以确定的一点是数据源是可索引的。算法通过尝试比较不同索引处的数据来确定目标数据的方向;另一方面,算法的使用方必定熟悉数据源,知道索引便能确定具体数据。

因此,此算法忽略具体的数据源,而要求调用者告之数据源的索引范围,并提供对指定索引处数据进行比较的逻辑(作为委托传入)。

这样,算法只需操作索引,而得以与具体的数据源隔离,比较逻辑与可以由用户自定义。

示例:

代码
SearchAlgorithm.BiSearchMatch Match  =   delegate ( int  Index)
            {
                
return  BranchID.CompareTo(AllBranchList[Index].ID);
            };
ElementIdx 
=  SearchAlgorithm.BiSearch( 0 , AllBranchList.Count  -   1 , Match);


源码:

 

代码
         ///   <summary>
        
///  折半查找的Match参数原型
        
///   </summary>
        
///   <param name="Index"> BiSearch生成的索引 </param>
        
///   <returns> 0:索引处的数据匹配成功;1:要寻找的数据在索引与上界之间;-1:要寻找的数据在索引与下限之间 </returns>
         public   delegate   int  BiSearchMatch( int  Index);

        
///   <summary>
        
///  折半查找:此函数将根据上下界按折半查找规则生成可能的索引,并使用生成的索引逐个调用Match委托,直到匹配成功或没有其它可能的索引。
        
///   </summary>
        
///   <param name="LBound"> 下界 </param>
        
///   <param name="UBound"> 上界 </param>
        
///   <param name="Match"> 匹配委托 </param>
        
///   <returns> 若返回值在(LBound,UBound)区间内,则查找成功且返回值即为要寻找的索引;若返回值小于下限,则表示未找到要寻找的索引。 </returns>
         public   static   int  BiSearch( int  LBound,  int  UBound, BiSearchMatch Match)
        {
            
int  Mid,Result,TempLBound  =  LBound;

            
if  (LBound  >  UBound  ||  Match  ==   null return  LBound  -   1 ;

            
while (LBound  <=  UBound)
            {
                Mid 
=  LBound  +  ((UBound  -  LBound)  >>   1 );
                Result 
=  Match(Mid);

                
if  (Result  ==   0 )
                    
return  Mid;
                
else   if  (Result  >   0 )
                    LBound 
=  Mid  +   1 ;
                
else
                    UBound 
=  Mid  -   1 ;
            }

            
return  TempLBound  -   1 ;
        }


 

你可能感兴趣的:(二分查找)