二分查找原理与分析

来源:互联网 发布:windows找不到social 编辑:程序博客网 时间:2024/06/05 03:46

时间:2014.04.01

地点:基地二楼

------------------------------------------------------------------------------------

一、概述

  嗯,二叉查找的思想还是很简单的,在有序数组的查找中非常有用,比如在按字母排序的字符串中查找,对按序排列的号码查找。我们在设计这个二叉查找的函数时可指明:

1.数组本身 2.查找起始下标 3.查找元素的个数 4.查找目标 5.查找情况 6.位置。函数原型如下:

viod search(const int a[],size_t first,sizet_t size,int target,bool& found, size_t& location
//前置条件:数组a从小到大排序

//后置条件:从a[first]开始,含size个元素的数组段内查找给定元素target,找到found为true,并设置location,否则found设置为false

-----------------------------------------------------------------------------------

二、设计

递归实现,算法的伪代码如下:

if(size==0)  found=false;else{  middle=数组段近似中点的下标;  if(target==a[middle])    目标在a[middle]处找到  else if(target<a[middle])    在中间点的前面部分查找目标  else if(target>a[middle])    在中间点的后面部分查找目标}

在算法的递归实现中,我们必须保证函数的递归能够正确地终止,因此每次递归调用都会查找一个更小的列表,当列表长度为0时不再继续递归调用。在这里size是一个有效的变量表达式,阈值为0,即size没调用一次,都至少会减少1,size为0时不再继续调用。

-----------------------------------------------------------------------------------

三、函数的实现

viod search(const int a[],size_t first,size_t size,int target,bool& found,size_t& location)//Precondition: ......//Postcondition: ......//Library facilities used: {  size_t middle;  if(size==0)    found=false;  else{    middle=first+size/2;    if(target==a[middle){        loacatin=middle;            found=true;    }    else if(target<a[middle])        search(a,first,size/2,target,found,loacation);    else        search(a,middle+1,(size-1)/2,target,found,location);  }}

这里有几个经验总结和常见错误

1.已知数组起始索引first和元素个数size,求近似中间元素索引公式为:

middle=first+size/2

2.已知数组元素个数为size,那么以中间元素为分界,两边都不包活中间元素,则左边段含有size/2个元素,右边段含有 (size-1)/2个元素

3.数组连续索引区间上[a,b)共含有 b-a 个元素

4.你应该尽量避免为负的size_t值,以免程序在运行时发生错误。

-----------------------------------------------------------------------------------

四、分析

  二叉查找最坏的情况就是查找目标不在数组中,如此会一次又一次的递归下去,直到size一半一半的减少到0,没迭代一次,size都会在原来的基础上缩小一半,

这里有个概念叫做递归调用深度:即最长递归调用链的长度。在n个元素的数组中进行二叉查找的递归调用深度最多为n被2除的次数,当结果小于1时停止。

所以二叉查找的最坏运行时间T(n)=(每次最坏迭代运算次数)*(最长递归调用链长度)+停止情况时执行的运算次数

                                                           =18*(最长递归调用长度)+2

                                                           =18*(n可以被2除的次数,当结果小于1时停止)+2

                                                           =18*H(n)+2

H(n)为二分函数,可以看出H(n)约等于以2为底的n的对数,即log2(n),更准确地说二分函数的值H(n)=floor(  log2(n)  )+1
,在分析算法效率时我们常丢掉常数部分,认为该算法的最坏情况运行时间是对数级别的,即O(log n)。

总结:对于有n个元素的数组来说,二叉查找的算法最坏运行时间是对数级的,为O(log n)

0 0
原创粉丝点击