基础算法(二)---数据结构之树

基本概念:

  1. 深度:从根节点到该节点的路径长度
  2. 高度:从该节点到叶节点的路径长度
  3. 树的高度=根的高度

知识点小总结:

  • 平均二叉树:有N个节点,平均深度为(根号N)
  • 二叉查找树:有N个节点,平均深度为(logN)

    N个节点的二叉树,有N+1个NULL节点

  • 表达式树:叶子为操作数其他为操作符的树

中序遍历—>标准表达式
后序遍历—>后缀表达式
先序遍历—>前缀表达式

二叉查找树:

对于树中的每个节点X,它的左子树中所有项的值小于X中的项;它的右子树中的所以的项的值都大于X中的项

  • 插入:为将X插入树T中,沿着树查找,如果找到X则什么也不做;否则将X插入到遍历路径的最后一个节点

PS:重复元的插入可以通过在节点记录中保留一个附加域以指示发生的频率来处理;这对整个树增加了某些附加空间,但却比将重复信息放在树中更好。

  • 删除:(被删除节点有以下几种情况)
  1. 如果节点是一个叶子节点:可以立即被删除
  2. 如果节点有一个儿子:该节点可以在其父节点调整自己的链,以绕过该节点后被删除
  3. 如果节点有两个儿子:一般的删除策略用其有儿子树的最小的数据代替该节点的数据,并递归的删除那个节点【因为右子树的最小节点不可能有左儿子,所以第二次操作删除它容易实现】

AVL树

AVL树是带有平衡条件的二叉查找树,保证树的深度我o(logN)。一棵AVL树是其每个节点的左子树和右子树的高度最多差1的二叉查找树(空树的高度定义为-1)。

对AVL树进行插入时,树的平衡性可能会被破坏,因此要在插入之后插入完成之后恢复平衡性质,我们使用旋转来完成这个恢复平衡的操作。

在插入以后,只有那些从插入点到根节点的路径上的节点的平衡可能被改变。当沿着这条路径上行到根并更新平衡信息时,可以发现一个节点,它的新平衡破坏了AVL条件。如何在第一个这样的节点(即最深的节点)重新平衡这棵树。

把必须重新平衡的节点叫作a,由于任意节点最多有两个儿子,因此出现新高度不平衡就需要a点的两棵子树的高度差为2,这种不平衡可能出现在下面四种情况中:

  1. 对a的左儿子的左子树进行一次插入(左左)
  2. 对a的左儿子的右子树进行一次插入(左右)
  3. 对a的右儿子的左子树进行一次插入(右左)
  4. 对a的右儿子的右子树进行一次插入(右右)

第1和4是关于a点的镜像对称,同理第2和3也是,因此理论上只存在2种情况

  1. 插入发生在外边的情况(左-左或右-右)—-单旋转
  2. 插入发生在内边的情况(左-右或右-左)—-双旋转

单旋转:

单旋转调整(左左)的处理如下图

这里写图片描述

  1. 插入的节点为X2,
  2. 节点K2不满足AVL平衡性质,子树X(包括X1和X2)多长出来了一层,使得它不子树Z深出2层
  3. 为使得树回复平衡性,把X上移一层,把Z下移一层
  4. 原树中K2大于K1,于是在新树中K2变为K1的右儿子,X和Z还分别是K1的左二子和K2的右儿子
  5. 原树中Y介于K1和K2之间,将其放在新树中K2的左二子

这样的操作只需要一部分的链改变,结果我们得到另外一颗二叉查找树,它是一颗AVL树,子树都处在同一个高度。整棵树的新高度和原高度一致

单旋转调整(右右)的处理如下图

这里写图片描述
插入节点为Z2,调整步骤和上面类似。

双旋转:
双旋转调整(左右)的处理如下图
这里写图片描述
插入的是Y1或者Y2

问题在于子树Y太深,单旋转没有减低它的深度

  1. 为了重新平衡,唯一的选择就是把K2作为新的根
  2. K1称为K2的左儿子,K3成为K2的右儿子

PS:这样的操作其效果和先在a节点的儿子和孙子之间旋转而后再在a节点和它新的儿子之间旋转

重新平衡后的树的高度和原高度一致

双旋转调整(右左)的处理如下图
这里写图片描述

算法步骤:
为了将项X插入到一棵AVL树中。递归地将X插入到T的相应子树(T-LR)中。
1. 将X插入T-LR中,如果T-LR高度不变,插入完成
2. 如果在T中出现高度不平衡,则更具X以及T和T-LR中的项做适当的单旋转或者双旋转,更新高度,完成插入操作

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值