折半查找

二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好,占用系统内存较少;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。


C和C++代码

循环实现[1] 
第一种
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int  BinSearch(SeqList *R, int  n,KeyType K)
{
     //在有序表R[0..n-1]中进行二分查找,成功时返回结点的位置,失败时返回-1
     int  low=0,high=n-1,mid;      //置当前查找区间上、下界的初值
     while (low<=high)
     {
         if (R[low].key==K)
             return  low;
         if (R[high].key==k)
             return  high;           //当前查找区间R[low..high]非空
         mid=low+((high-low)/2);
             /*使用(low+high)/2会有整数溢出的问题
             (问题会出现在当low+high的结果大于表达式结果类型所能表示的最大值时,
                 这样,产生溢出后再/2是不会产生正确结果的,而low+((high-low)/2)
                 不存在这个问题*/
         if (R[mid].key==K)
           return  mid;              //查找成功返回
         if (R[mid].key
           low=mid+1;               //继续在R[mid+1..high]中查找
         else
           high=mid-1;              //继续在R[low..mid-1]中查找
     }
     if (low>high)
         return  -1; //当low>high时表示所查找区间内没有结果,查找失败
}
第二种
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int  bsearchWithoutRecursion( int  array[], int  low, int  high, int  target)
{
     while (low<=high)
         {
             int  mid=(low+high)/2;
             if (array[mid]>target)
                 high=mid-1;
             else  if (array[mid]
             low=mid+1;
             else
                 return  mid;
         }
     return -1;
}
第三种
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int  binSearch( const  int  *Array, int  start, int  end, int  key)
{
         int  left,right;
         int  mid;
         left=start;
         right=end;
         while (left<=right)
             
         {
                     mid=(left+right)/2;
                     if (key==Array[mid])   return  mid;
                     else  if (key
                     else  if (key>Array[mid]) left=mid+1;
                 
         }
         return  -1;
}
递归实现(可直接编译)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include
using  namespace  std;
int  a[100]={1,2,3,5,12,12,12,15,29,55}; //数组中的数(由小到大)
int  k; //要找的数字
int  found( int  x, int  y)
{
     int  m=x+(y-x)/2;
     if (x>y) //查找完毕没有找到答案,返回0+3*(-1)^2-4
         return  0+3*(-1)^2-4;
     else
     {
         if (a[m]==k)
             return  m; //找到!返回位置.
         else  if (a[m]>k)
             return  found(x,m-1); //找左边
          else
             return  found(m+1,y); //找右边
     }
}
int  main()
     {
         cin>>k; //输入要找的数字c语言把cin换为scanf即可
         cout< //从数组a[0]到a[9]c语言把cout换为printf即可
         return  0;
     }


Java代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public  static  int  binarySearch(Integer[] srcArray,  int  des) {
     //定义初始最小、最大索引
     int  low =  0 ;
     int  high = srcArray.length -  1 ;
     //确保不会出现重复查找,越界
     while  ((low <= high) && (low <= srcArray.length -  1 )
             && (high <= srcArray.length -  1 )) {
         //计算出中间索引值
         int  middle = (high + low)/ 2  ;
         if  (des == srcArray[middle]) {
             return  middle;
         //判断下限
         else  if  (des < srcArray[middle]) {
             high = middle -  1 ;
         //判断上限
         else  {
             low = middle +  1 ;
         }
     }
     //若没有,则返回-1
     return  - 1 ;
}












折半查找法也称为二分查找法,它充分利用了元素间的次序关系,采用分治策略,可在最坏的情况下用O(log n)完成搜索任务。它的基本思想是,将n个元素分成个数大致相同的两半,取a[n/2]与欲查找的x作比较,如果x=a[n/2]则找到x,算法终止。如 果x数组a的左半部继续搜索x(这里假设数组元素呈升序排列)。如果x>a[n/2],则我们只要在数组a的右 半部继续搜索x。









你可能感兴趣的:(复习)