二叉排序树及二叉平衡排序树(暂无代码实现c)

二叉排序树

定义:

  1. 二叉排序树可以是一颗空树,或者是满足下列性质的二叉树
    1. 若左子树不为空,则左子树上所有结点值均小于它根结点的值
    2. 若左右子树不为空,则右子树上所有结点值均大于它根结点的值
    3. 左右子树也均为二叉排序树

 特点:当通过中序遍历一颗二叉排序树时,得到的时一个递增序列

查找

算法思想

  1. 如果二叉排序树空,则查找失败,返回空指针
  2. 若不为空,则将给定数值key与根节点的关键字T->data.key比较:
    1. 若key==T->data.key,则查找成功,返回根节点地址
    2. 若key>T->data.key,则递归查找右子树
    3. 若key<T->data.key,则递归查找左子树

例如上图中,我们查找89:

  1. 由于二叉排序树不为空,则先于根节点的关键字43比较,发现比43大,因此进入右子树
  2. 右子树不为空,与其内的78比较,发现比78大,因此继续进入右子树
  3. 右子树不为空,与其内的89比较,发现相等,因此查找成功,返回该结点地址 

平均查找长度  ASL=(∑对应层数*对应层数内的结点数)/结点总数

例如上图的 ASL=(1*1+2*2+3*3+4*1+5*1)/8=2.875

插入

算法思想:

  1. 如果二叉排序树为空,则带插入结点s作为根节点插入到空树中
  2. 若二叉排序树非空,则将值key与根节点的关键字T->data.key进行比较:
    1. 若key>T->data.key,则将s插入左子树(插入后继续比较,直至成为终端结点)
    2. 若key<T->data.key,则将s插入右子树(插入后继续比较,直至成为终端结点)

创建

 在插入的基础上进行二叉排序树的创建

要明白一点,对于同一堆数值,不同的输入顺序会得到不同的二叉排序树

例如,对于(43,67,23,89,56,18,34)

打乱顺序,对于(23,56,34,43,18,89,67) 

 

删除 

关键:删除结点以后仍要保持二叉排序树的性质

删除的是叶子结点:直接删除结点即可

删除的结点只有左子树(右子树):直接用左孩子(右孩子)覆盖掉原结点即可

删除的结点既有左子树又有右子树

  1. 用该结点的中序遍历里的前驱结点代替他,对于他的前驱结点进行上述相同的操作
  2. 或者用该节点的中序遍历中的后继结点代替他,对于他的后继结点进行上述相同的操作

例如, 

 

 要删除结点50

中序遍历序列为:20、30、32、35、40、45、50、80、85、88、90

  1. 由于结点50既有左子树又有右子树,先用其前驱40代替结点50
  2. 对于结点40,由于其也既有左子树又有右子树,则再用其前驱35代替结点40
  3. 对于结点35,由于其只有左子树,则直接用左孩子替代即可

删后结果为, 

 平衡二叉树(AVL树)

定义:

  1. AVL树可以是空树,或者是具有以下性质的二叉树
    1. | 左子树depth - 右子树depth | ≤ 1
    2. 左子树和右子树也是AVL树
  2. 平衡因子BF:左子树与右子树的深度之差【AVL树中的BF只可能是-1、0、1】

平衡调整: 

失衡:平衡因子不再是-1、0、1

例如,在插入60后,结点53的平衡因子变成-2

调整原则 :

  1. 不止一个失衡结点时,找到失衡的最小平衡因子的结点
  2. 降低高度,保持二叉排序树性质

LL型 【插入结点为左子树的左子树】

方法:顺时针旋转法

  1. 左子树B 带着 左子树B 的 左子树C 上移【左子树B的右子树D断裂】
  2. 原根节点A 成为 原左子树B 的右孩子
  3. 原左子树B 的 右子树D 成为 原根节点A 的左子树

RR型【插入结点为右子树的右子树】

 方法:逆时针旋转法

  1. 右子树B带着右子树B的右子树C上移【右子树B的左子树D断裂】
  2. 原根节点A 成为 原右子树B的左孩子
  3. 原右子树B 的 左子树D 成为 原根节点A 的右子树

 

 LR型【插入结点为左子树的右子树】

方法:先逆后顺法

  1. 先对左子树B和左子树B的右子树C进行一次逆旋转,B成为C的左孩子【此时成为LL型】
  2. 进行LL型的调整

RL型【插入结点为右子树的左子树】

方法:先顺后逆法

  1. 先对右子树B和右子树B的左子树C进行一次顺旋转,B成为C的右孩子【此时成为RR型】
  2. 进行RR型的调整

 试炼:构建序列为(16、3、7、11、9、26、18、14、15)的AVL树

结果:

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值