二叉排序树
- 左子树的所有节点值小于根节点的值
- 右子树的所有节点值大于根节点的值
- 左右子树又分别是一棵二叉排序树
二叉排序树节点的删除
- 若删除的节点是叶子节点,直接删去
- 若删除的的节点有左子树且无右子树,则用左子树代替被删除节点、
- 若删除的的节点有右子树且无左子树,则用右子树代替被删除节点、
- 若删除的节点p同时有左右子树,为了删除后满足二叉排序树的定义,可以从其左子树选择关键字最大的节点r,用r的值替换p的值(节点值替换),并删除节点r(由于节点r一定没有右子树,删除它属于情况2)。
void Delete1(BSTNode * p,BSTNode * &r){//被删除节点p有左右子树,r指向其左孩子
BSTNode * q;
if(r->rchild!=null)//递归找节点r的最右下节点
Delete1(p,r->rchild);
else//找到了最右下节点r(它没有右子树)
{
p->key=r->key;//将节点r的值存到节点p
p->data=r->data;
q=r;
r=r->lchild;//删除节点r,即用它的左孩子替代它
free(q);//释放节点q的空间
}
}
平衡二叉树
为了防止二叉排序树出现退化成链表的情况,出现了平衡二叉树(在二叉排序树的基础上新增规则:每个节点左子树的高度与右子树高度之差的绝对值不超过1)。一般情况下,一颗平衡二叉树总是二叉排序树。
平衡二叉树的调整
调整规则
- 假设找到某个节点的平衡因子为-2;其右孩子的平衡因子是-1,则作RR调整;其右孩子的平衡因子是1,则作RL调整;其右孩子的平衡因子是0,则做RR或RL调整均可。
- 假设找到某个节点的平衡因子为2;其左孩子的平衡因子是-1,则作LR调整;其左孩子的平衡因子是1,则作LL调整;其左孩子的平衡因子是0,则做LR或LL调整均可。