【数据结构】折半查找及其二叉判定树画法

折半查找又叫二分查找,是数据结构中一种很重要的查找方式。

其特点有以下几个:

  1. 只能对有序的顺序表进行查找。
  2. 是一种静态查找。
  3. 查找的平均时间复杂度为o(log2n)。
  4. 成功平均查找长度ASL约log2(n+1)-1。

这里要注意折半查找和二叉排序树查找的区别。折半查找和二叉排序树查找的平均查找长度均取决于树高h(或折半查找判定树的高h),折半查找的判定树的高只与序列长度n相关(必为平衡二叉树AVL树),而二叉排序树查找构建二叉排序树时树的高度还取决于序列顺序。所以折半判定树树高始终为log2(n+1)向上取整,而在最优情况下二叉排序树树高最低为log2(n+1)向上取整,最坏情况下(序列有序)树高h为n;因此折半查找最多比较次数为log2(n+1)向上取整,而二叉排序树最优情况下与此相等,最坏情况下为n次。

以下给出一个折半查找的C++代码:


 
 
  1. #define MaxSize 50;
  2. using namespace std;
  3. struct SeqList{
  4. Elemtype elem[MaxSize];
  5. int Length;
  6. };
  7. int Binary_Search(SeqList L,Elemtype x)
  8. {
  9. int low= 0,high=L.Length -1,mid;
  10. while(low<=high)
  11. {
  12. mid=(low+high)/ 2;
  13. if(x==L.elem[mid])
  14. return mid;
  15. else if(x<L.elem[mid])
  16. high=mid -1;
  17. else
  18. low=mid+ 1;
  19. }
  20. return -1;
  21. }

 可以看出折半查找的代码相对非常简单。在实际的考题中,往往会出现对具体个数的序列的折半查找等概率下的成功查找长度和失败查找长度,解决这类问题需要画出对应的二叉判定树。有时甚至会出现直接对于某二叉判定树的问题(如某具体序列中查找某元素的比较顺序或某序列的最大比较次数等问题)。

以下给出我在学习中总结的一种比较简便的构造折半二叉判定树的思路以及方法:

思路分析:

在计算mid值时,使用的时mid=(low+high)/2  。这里由于mid为int类型,自动默认为向下取整,因此对于一个长度为n序列进行划分之后的序列为 (0,1,2,……,mid-1)mid(mid+1,mid+2,……n-1),此时出现两种情况:

  • 左子序列长==右子序列长      (n=2k+1    k=0,1,2,……)
  • 左子序列长==右子序列长-1   (n=2k        k=1,2,3,……)

因此可以得知,折半查找的二叉判定树对于所有结点,左子树结点个数<=右子树结点个数。即:

  1. 若某序列总长n为奇数,左右子树结点个数相等;
  2. 若某序列总长n为偶数,左字数结点个数=右子树结点个数-1.

由此给定某个序列,构建折半查找判定树方法如下三步:

  1. 按照二叉树每层最大结点数为2^(h-1)依次由上至下构建满二叉树至最底层不够形成满二叉树为止。
  2. 将剩余结点按照上述粉字的规律依次填入最底层即为二叉判定树的树形。
  3. 按照中序遍历顺序将各结点值填入结点即可。

具体如下面的例子:

 

例:画出(2,5,7,10,14,15,18,23,35,41,52)的折半查找判定树。

1.序列总长度为n=11>2^3-1=7     即二叉判定树为4层,第4层不满。

2.

1)剩余四个结点。当第四层一个叶结点时,结点总数n=8为偶数,因此对于a来说,应加在a的右子树,即c的子树中;对于c来说,结点总数n=4为偶数,应加在c的右子树中,即g的子树中;对于g来说,结点总数n=2为偶数,应加在g的右子树,即

2)在第四层加入第二个结点时,结点总数n=9为奇数,因此对于a来说,应加在a的左子树使左右子树结点个数相等,即加在b的子树中;对于b来说,结点总数n=4为偶数,应加在b的右子树,即e的子树中;对于e来说,结点总数n=2为偶数,应加在e的右子树,即

3)同理分析,第三个结点应加在a的右孩子的左孩子的右子树,即

4)第四个结点加在a的左孩子的左孩子的右子树,即

得到最终的树形如上图。

3.该二叉树的中序遍历顺序为dkbeiafjcgh,因此将序列一一对应填入树中,即

该树即为此序列的二叉判定树。

 

做题过程中熟练使用此方法比通过算法模拟来推断二叉判定树的速度要快许多倍。

在平时做题过程中,涉及到需要具体画出二叉判定树的题目,往往结点个数(序列长度)不超过2^4-1=15个,即一般为高度不超过4的树,因此可以在练习时将结点个数8-14的所有树形画几遍,就可以很熟练的掌握这个方法。

二叉判定树画出之后便可以对其他具体题目进行分别的计算,如求成功或失败的查找长度、求比较顺序、比较次数等。

  • 28
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值