• 关于BST、AVL、红黑树的学习


       因为这段时间重新复习了数据结构的知识,学习到关于树与二叉树的应用时,进一步学习了之前没怎么在意的二叉搜索树(二叉排序树(BST)),二叉平衡树(AVL)。而之前看java中hashmap源码时了解到,在jdk1.7之前,hashmap是以数组+链表实现的,在jdk1.8之后便是用数组+红黑树来实现的,提高了查找的效率。所以这次把这三种树串起来一起学习。

    • 首先说一下这三种树的关系,规则限制  红黑树>AVL>BST,平均查找长度(最坏情况)——红黑树,AVL(O(logn))  ——BST(O(n))退化成了链表
    • AVL是为了避免BST的高度过度增长,降低BST的性能,从而定了某些规则来限制避免树的高度增长过快
    • 红黑树又相当于AVL树的一个扩展,一个子类,若AVL树频繁的删除或插入节点时,会导致AVL树的不平衡,从而频繁的做旋转,从而降低了性能,所以说AVL树比较适合做查找操作。而对于红黑树来说,虽然限制比较多一些,但是不会频繁的进行旋转,它有变色的功能,性能有所提升。红黑树旋转次数少,所以对于搜索,插入,删除操作较多的情况下,用红黑树。

      AVL一定是二叉搜索树,且AVL规则限制很简单:它的左子树和右子树都是平衡二叉树,且左子树与右子树的高度差绝对值不超过1。AVL每次调整的对象都是最小不平衡子树,所以关键是找到最小不平衡子树,从而进行旋转。

      AVL树在新节点插入后,造成查找路径上的某个节点不再平衡,则需要做出相应的调整,主要规则如下: 

    结点A的左孩子的左子树上插入了新节点,A的平衡因子由1增加至2,导致以A为根的子树失去平衡,需要一次向右旋转的操作 LL平衡旋转(右单旋转)
    结点A的右孩子的右子树上插入了新节点,A的平衡因子由1增加至2,导致以A为根的子树失去平衡,需要一次向左旋转的操作 RR平衡旋转(左单旋转)
    结点A的左孩子的右子树上插入了新节点,A的平衡因子由1增加至2,导致以A为根的子树失去平衡,需要进行两次旋转操作,一次先向左旋转的操作一次再向右旋转的操作 LR平衡旋转(先左旋再右旋)
    结点A的右孩子的左子树上插入了新节点,A的平衡因子由1增加至2,导致以A为根的子树失去平衡,需要进行两次旋转操作,一次先向右旋转的操作一次再向左旋转的操作 RL平衡旋转(先右旋再左旋)

      

      而红黑树又是特殊的AVL树,是对AVL树的一种扩展

      主要性质如下:

    • 根节点必须为黑丝;
    • 父子节点不能同为红色;
    • 从任何一个节点出发,到达叶子结点经过的黑色结点的数量一致;(此处的叶子结点是指NIL结点)
    • 每个红色结点的两个子节点都是黑色,叶子结点都是黑色。

      如果满足了以上的性质,就可以认为红黑色近似的平衡了。

      关于红黑树的插入,造成不平衡的情况,有以下旋转和颜色变换规则,与AVL有一些不同:

      首先,默认插入的结点都是红色,之后再进行调整

      

    1、变颜色
    插入结点的父亲结点以及叔叔结点都是红色
    (1)把父节点以及叔叔节点均设为黑色
    (2)把爷爷结点设为红色
    (3)把插入结点的爷爷节点作为下一次需要操作的对象
    2、左旋

    当前要操作结点的父节点是红色,而叔叔结点是黑色的且是
    父节点的右子树的时候,以当前结点的父节点进行左旋。

    3、右旋

    当前要操作结点的父节点是红色,而叔叔结点是黑色的且是父节点的左子树的时候,进行右旋:
    (1)把当前结点的父节点变为黑色
    (2)把当前结点的爷爷节点变为红色
    (3)之后以当前结点的爷爷结点开始进行右旋

  • 相关阅读:
    css中margin-left与left的区别
    Python文件和目录模块介绍:glob、shutil、ConfigParser
    [ Python入门教程 ] Python文件基本操作_os模块
    使用Pyinstaller转换.py文件为.exe可执行程序
    Windows命令行打开常用界面
    如何做好性能测试_流程篇
    Windows查看指定端口是否占用和查看进程
    ‘操作无法完成 ,因为其中的文件夹或文件已在另一程序中打开’问题解决
    bat脚本基础教程
    vi编辑器常用命令
  • 原文地址:https://www.cnblogs.com/zxgCoding/p/13342217.html
Copyright © 2020-2023  润新知