此算法于《算法》P257有描述
所谓向上取整就是指大于等于x的最小整数,向下取整是指小于等于x的最大整数
此算法在二叉查找树中查找大于等于x的最小整数/小于等于x的最大整数
算法主要分为几种情况讨论(以向上取整为例):
1.当前节点的键值小于x:目标肯定位于当前节点的左子树,因为右子树>当前节点>目标节点,所以不可能在右子树
2.当前节点的键值大于x:目标肯定位于当前节点的右子树或目标为当前节点,因为当前节点为此时已知的小于等于x的最大整数,若在右子树中查找失败,则目标就是当前节点
3.当前节点的键值等于x:目标为当前节点,返回
4.当前节点为NULL:查找失败,返回NULL
将以上思路用递归实现就OK了~
代码如下:
TreePosition FindFloor(ElementType X, Tree T)
{
TreePosition P;
if (T == NULL)
return NULL;
else if (X < T->Element)
//如果小于当前节点,则小于等于X的节点都在左子树内
return FindFloor(X, T->Left);
else if (X == T->Element)
//如果等于当前节点,满足条件
return T;
else
{
//如果大于当前节点,则小于等于X的节点在右子树内,若右子树内查找失败
//则当前节点为小于等于X的最大节点
P = FindFloor(X, T->Right);
if (P == NULL)
return T;
else
return P;
}
}
向下取整查找如法炮制,只需将Left与Right、<与>换下就OK~
代码如下:
TreePosition FindCeiling(ElementType X, Tree T)
{
TreePosition P;
if (T == NULL)
return NULL;
else if (X > T->Element)
//若大于当前节点,则大于等于X的最小节点一定在右子树内
return FindCelling(X, T->Right);
else if (X == T->Element)
return T;
else
{
//如果小于当前节点,则一定在左子树内,若查找失败,
//则当前节点为大于等于x的最小节点
P = FindCelling(X, T->Left);
if (P == NULL)
return T;
else
return P;
}
}
因为所有操作都沿着一条路径进行,而没有一条路径长于树的高度,所以时间复杂度为
O(logN)