折半查找及其判定树的性质
目录
折半查找——非递归版本
折半查找——递归版本
折半查找的判定树相关问题
判定树的节点个数和分类
判定树与平衡二叉树的关系
判定树与满二叉树的关系
判定树与完全二叉树的关系
判定树的树高h计算方法
ASL简便计算方法
判定一棵树是否是折半查找判定树
-
折半查找——非递归版本
以向下取整为例
int BinarySearch(int A[],int x,int n){int left=0,right=n-1;while(left<=right){int mid=(left+right)/2;if(A[mid]==x) return mid;else if(A[mid]>x) right=mid-1;else left=mid+1;}return -1;
}
-
折半查找——递归版本
以向下取整为例
int BinarySearch(int A[],int x,int left,int right){if(left>right) return -1;int mid=(left+right)/2;if(A[mid]==x) return mid;else if(A[mid]>x){return BinarySearch(A,x,left,mid-1);}else{return BinarySearch(A,x,mid+1,right);}
}int Search(int A[],int x,int n){return BinarySearch(A,x,0,n-1);
}
-
折半查找的判定树相关问题
-
判定树的节点个数和分类
数组长度为n的折半查找的判定树共有2n+1个结点,其中有n个成功结点,n+1个失败结点
以int型数组为例。n个有序元素将区间R划分为了n+1个开区间,如果要查找的元素落在这些开区间内,就会查找失败,因此失败节点一共有n+1个
-
判定树与平衡二叉树的关系
折半查找的判定树一定是一棵平衡叉树。每轮查找选取中间节点时,无论是上下取整还是向下取整,mid位置左右两侧的元素个数相差的绝对值不会超过1,这也就是意味着对于判定树中的任何一个结点,其左右子树的节点个数之差不会大于1
而平衡二叉树的定义是左子树和左子树的高度之差(平衡因子)的绝对值不超过1。折半查找的判定树的要求更加严格,要求的是左子树和右子树的节点个数绝对值之差不超过1。前者是对左右子树高度的限制,后者是对左右子树节点个数的限制。因此,折半查找的判定树一定是一个平衡二叉树,但中序序列为升序的平衡二叉树却不一定可以构成一个折半查找判定树
-
判定树与满二叉树的关系
一个h层折半查找的判定树(h>1),前h-1层一定是一棵满二叉树。
简要证明:假设前h-1层不是满二叉树。和h-1层的满二叉树相比,在第h-1层上一定会出现空缺的结点。而这个空缺的结点在第h-1、h层均会出现空缺。这就意味着树中某个节点的左右子树之差大于等于2了,这已经不满足平衡二叉树的定义,更不满足折半查找判定树的定义了
-
判定树与完全二叉树的关系
一个h层折半查找的判定树(h>1),前h-1层一定是一棵满二叉树。同样的,一个h层的完全二叉树,前h-1层也是一棵满二叉树。
折半查找判定树和完全二叉树的区别只在最后一层。如果将折半查找判定树的最后一层的结点全部向左靠拢,就会形成一棵完全二叉树
我们得到以下两条结论:
判定树的树高h计算方法
计算n个节点(不包含失败结点)的折半查找判定树的高度,和计算n个节点完全二叉树的高度方法完全相同,公式也一样。因为最后一层节点的位置不影响树高
ASL简便计算方法
计算ASL时也可以直接画完全二叉树,因为最后一层节点的位置不影响查找长度,对于查找成功或查找失败的情形均无影响
-
判定一棵树是否是折半查找判定树
1. 中序遍历序列为升序
2. 前h-1层是满二叉树
3. 是平衡二叉树
4. 任意一个节点,左右子树的节点个数差的绝对值不超过1
5. 最终判断
两种情形
向下取整算法:任意一个节点,要么左右子树节点个数相等,要么左子树节点个数都比右子树节点个数少1
向上取整算法:任意一个节点,要么左右子树节点个数相等,要么左子树节点个数都比右子树节点个数多1
