要定位隐藏的结点,以递归的方式调用hide,直到找到目标为止。一旦将结点隐藏了,就没有必要重新平衡树了,因为并没有对树的结构做任何修改。因此,直接将balanced值设置为1。
从AVL树中移除结点的过程分析同插入结点一样,因此bistree_remove的时间复杂度为O(lg n)。
从AVL移除结点的过程分析同插入结点一样,因此,bistree_remove的时间复杂度为O(lgn)。
bistree_lookup
该操作用来在二叉搜索树中查找结点。返回一个指向AvlNode结构体中数据域成员的指针。该操作通过递归的方式调用lookup,从根结点开始,逐层降低遍历树的结点,直到找到目标结点为止。在每个层级上,我们首先检查是否到达了分支的边缘。如果我们处于分支的边缘就说明我们要找的结点不存在。否则,我们要么移动到左子结点,要么移动到右子结点,移动方式同前面介绍过的bistree_insert一样。当我们遇到目标结点时,递归终结,此时返回0。
查找Avl树中结点的分析过程同插入结点一样,因此bistree_lookup的时间复杂度为O(lg n)。
bistree_size
这是一个宏,用来计算二叉搜索树中结点的个数。直接访问BisTree结构体中的size成员即可。
示例:二叉搜索树抽象数据类型的实现/*bistree.c*/
#include <stdlib.h>
#include <string.h>
#include "bistree.h" /*bistree.h中包含bitree.h*/
static void destroy_right(BisTree *tree,BiTreeNode *node);
/* rotate_left 执行LL或LR旋转*/
static void rotate_left(BiTreeNode **node)
{
BiTreeNode *left, *grandchild;
/*设left为A的左子树*/
left = bitree_left(*node);
/*left结点的平衡因子为1,说明新插入的结点位于A的左子树的左子树上*/
if(((AvlNode *)bitree_data(left))->factor == AVL_LFT_HEAVY)
{
/*perform an LL rotation. 执行LL旋转*/
bitree_left(*node) = bitree_right(left); /*A的左指针指向left的右子结点*/
bitree_right(left) = *node; /*left的右指针指向A*/
((AvlNode *)bitree_data(*node))->factor = AVL_BALANCED; /*旋转后,将A的平衡因子改为0*/
((AvlNode *)bitree_date(left))-factor = AVL_BALANCED; /*旋转后,将left的平衡因子改为0*/
*node = left; /*将原来指向A的指针指向left*/
}
/*left结点的平衡因子不为1,说明插入的结点位于A的左子树的右子树上*/
else
{
/*perform an LR rotation. 执行LR旋转*/
grandchild = bitree_right(left); /*设grandchild为left的右子结点*/
bitree_right(left) = bitree_left(grandchild); /*将left的右子结点指向grch的左子结点*/
bitree_left(grandchild) = left; /*将grch的左子结点指向left*/
bitree_left(*node) = bitree_right(grandchild);/*将A的左子结点指向grch的右子结点*/
bitree_right(grandchild) = *node; /*grch的右子结点指向A*/
/*执行LR旋转后,调整结点的平衡因子取决于旋转前grch结点的原平衡因子值*/
switch(((AvlNode *)bitree_data(grandchild))->factor)
{
case AVL_LFT_HEAVY: /*如grch原平衡因子值为1,就将A的平衡因子设为-1,left的设为0*/
((AvlNOde *)bitree_data(*node))->factor = AVL_RGT_HEAVY;
((AvlNode *)bitree_data(left))->factor = AVL_BALANCED;
break;