二叉查找树·AVL树·伸展树

一:二叉查找树

二叉查找树的特征是:根节点的左孩子小于根节点,而根的右孩子大于根节点。二叉查找树的平均深度为O(logN)。
  对于重复的元素,可以采用在节点记录中保留一个附加域以指示发生的频率来处理。

二:AVL树

AVL树是带有平衡条件的二叉查找树,这个平衡条件必须要容易保持,而且必须保证树的深度必须是O(logN),一棵AVL树是其每个节点的左子树和右子树的高度最多差1的二叉查找树
  当插入节点破坏了AVL树的特性,那么就需要考虑在这一步插入完成之前恢复平衡的性质。这里通过旋转来完成。必须要重新平衡的点叫做a,这种不平衡的情况一般有以下4种:
  1.对a的左儿子的左子树进行一次插入;
  2.对a的左儿子的右子树进行一次插入;
  3.对a的右儿子的左子树进行一次插入;
  4.对a的右儿子的右子树进行一次插入;
  对于情况1和4,发生在“外边”,可以采用对树的一次单旋转而完成调整,而对于2和3这种情况,可以采用对树的双旋转来处理。
  单旋转包括左旋右旋,左旋就是针对1的情况,将a的左儿子的右子树作为a的左子树(k2.left = k1.right),将a及其子树作为a的左儿子的右子树(k1.right = k2),其中k2就是节点a,而k1是它的左儿子。右旋同理。
  双旋包括左-右旋转右-左旋转。其实就是两次单旋,就是先在a的儿子和孙子之间旋转而后再在a和它的新儿子之间旋转。实质上双选包括三个节点,分别为a(k1),a的儿子(k3),a的孙子(k2),如果k3是k1的右孩子,而k2是a的左孩子,那么这种情况就需要右-左旋转,先在k3和k2之间进行左旋,之后再在k1和新的节点之间做右旋。

三:伸展树

伸展树保证从空树开始连续操作M次对树的操作最多花费O(MlogN)的时间。伸展树的基本思想是,当一个节点被访问后,它就要经过一系列AVL树的旋转被推到根上。
  伸展树最主要的思想就是展开,以保证在下一次访问附近节点的时候,效率提高。那么,如何进行展开呢,展开的具体做法就是:首先一棵树,从根节点到该节点的访问路径上,这条路径可能呈“之字型”或者“一字型”,如果呈“之字型”,那么从该访问节点开始,与其父节点做单旋,完成之后,形成的新树,再判断新树是成什么形状,如果还是“之字型”,那么和前一次同理,如果是“一字型”,那么就从根节点和此路径上的根节点的儿子节点做旋转(以儿子节点为新根旋转),逐渐将原访问节点旋转到根节点处。
  展开操作不仅将访问节点移动到了根节点处,而且还把访问路径上的大部分节点的深度大致减少一半(某些浅的节点最多向下推后两层)。

你可能感兴趣的:(数据结构之路,数据结构和算法之树)