查找

来源:互联网 发布:日本人茶点的知乎 编辑:程序博客网 时间:2024/04/29 21:02

查找:

  • 性能主要取决于键比较的次数
  • 平均次数:所有可能的(按照程序中的所有分支情况)键比较次数除以元素个数
  • 顺序查找
  • 插值查找:类似于查字典
  • 二分查找
    • 计算范围的中间位置,根据比较结果逐渐缩小范围
    • 注意循环和停止的条件
    • 方法1:无论是否找到都继续缩小范围
//每次进行1次比较if( data<target ) bottom=position+1;//起始位置else top=position-1;//结束位置
  • n=10
    方法1查找树(P237)的1半树叶对应成功的查找,另1半对应失败的查找。外部路径长度恰好为总的比较次数。成功/不成功的查找次数都为4.4(n=10时)。

  • 一般情况
    根据方法1查找树,所有的树叶(由于方法1最后只剩下1个元素,相等则成功,不相等则失败,所以成功/不成功的树叶都为n个)都在相同/相邻的层上,比较次数最多相差1次。

    由于每次只能选择1种情况,即在树的每层只能遍历1次,所以树的高度(层数)即为平均的(成功/不成功)查找次数lgn,最坏情况为lgn+1。

  • 方法2:找到结果后停止搜索

//每次进行2次比较if( data==target ) return success;if( data<target ) bottom=position+1;else top=position-1;
  • n=10

    • 方法2查找树(P238)的所有树叶都对应于不成功的查找。内部路径长度刚好对应第2项比较的次数19次。由于还需要计算第1项比较的次数,需要在计算内部路径长度每项的基础上加1(每经过一个节点都会有1次成功相等的判断),结果为29次。所以平均的成功次数为4.8;
    • 外部路径长度为39,对应第2项比较的次数。由于当比较结果不相等时,还需要继续比较,所以29不能作为第1项比较的次数。根据P238图7.4的圆圈中的示意图,在考虑第1项的情况下,外部路径比较刚好比原路径增长了1倍(由于现在进行的是不成功的比较,所以每次递归的2次比较都会进行)。由于n个元素有n+1个空缺(不成功的情况),所以平均的不成功次数为7.1。
  • 一般情况

    • 由于树叶的个数为n+1个,所以有h≈lg(n+1).因为每个节点进行2次比较,所以不成功的平均比较次数为2lg(n+1)
    • 由上知到树叶的距离为lg(n+1),且树叶的数目为n+1,所以E=(n+1)lg(n+1),根据E=I+2q可知I=(n+1)lg(n+1)-2n。所以成功的平均比较次数l/n*2-1(先算2次比较再减去最后1次相等后无需再进行大小比较)

总结:

  1. 当n比较大时,n与n+1、lgn和lg(n+1)的差距可以忽略不计。随着n的增加,有越来越多的结点会出现在底层。由于顶层的结点远小于底层,会有越来越多的顶点不能在顶层终止。
  2. 因为二分查找的循环次数lgn少于顺序查找的循环次数n,所以n比较大时,二分查找的速度远快于顺序查找。
  3. 对于2-树,为了减少树的高度(循环次数),将相差2层以上 的树叶分到上层树叶的子节点。
  4. 注意区分算法在小型问题和大型问题运行的效率。