首页 > 数据结构 > 查找 阅读:57,774

折半查找

折半查找又叫二分查找,首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。

 

折半查找过程演示,如下图所示,表中元素按升序排列:

 

假如要查找一个数据253。那么首先查看表中中间位置(0+8)/2即位置为4的元素:53。因为25353要大,所以丢弃表中04的子表数据,剩下58的字表数据。然后再计算58的子表的中间位置(5+8)/26的位置的元素:101。因为253101的数据要大,所以丢掉56子表中的元素,剩下78子表的元素。然后找到78中间位置(7+8)/27所在位置的元素:253,二者相等,那么查找成功,即所在位置为7

 

假如要查找一个为3的数据。那么首先查看表中中间位置(0+8)/2即位置为4的元素:53。因为353要小,所以丢掉48之间的子表元素,保留03之间的子表元素。然后在计算03之间的中间元素(0+3)/21所在位置的元素:9。因为39要小,所以丢掉13之间子表元素,留下0位置的元素1,但31要大。所以整个表查完,没有找到该元素,查找失败。

 

下面是折半查找算法:

//a为存放数据的有序表,n为数据元素个数,k为要查找的元素

int BinSearch(int a[], int n, int k)

{

     int low, high, mid, find, i;

    

     find = 0;

     low = 0;

     high = n-1;

 

     while (low <= high && !find)

     {

         mid = (low + high)/2;

         if (a[mid] < k)

              low = mid + 1;

         else if (a[mid] > k)

              high = mid - 1;

         else

         {

              i = mid;

              find = 1;

         }

     }

     if (!find)

         i = -1;

     return i;

}

递归版本:

 

int IterBiSearch(int data[], const int x, int beg, int last)  

{  

    int mid = -1;  

    mid = (beg + last) / 2;  

    if (x == data[mid])  

    {  

        return mid;  

    }  

    else if (x < data[mid])  

    {  

        return IterBiSearch(data, x, beg, mid - 1);  

    }  

    else if (x > data[mid])  

    {  

        return IterBiSearch(data, x, mid + 1, last);  

    }  

    return -1;  

 

int BinSearch(int a[], int n, int k)

{

    return  IterBiSearch(a,k,0,n-1);

}

注意:折半查找必须满足两个条件:一,元素必须是连续存储;二,元素必须有序。时间复杂度:O(logn)

周哥教IT,分享编程知识,提高编程技能,程序员的充电站。跟着周哥一起学习,每天都有进步。

通俗易懂,深入浅出,一篇文章只讲一个知识点。

当你决定关注「周哥教IT」,你已然超越了90%的程序员!

IT黄埔-周哥教IT技术交流QQ群:213774841,期待您的加入!

二维码
微信扫描二维码关注