20172311《程序设计与数据结构》第七周学习总结

20172311《程序设计与数据结构》第七周学习总结

教材学习内容总结

第十一章 二叉查找树

  • 二叉查找树是一种含有附加属性的二叉树,即其左孩子小于父节点,而父节点又小于等于右孩子
  • 二叉查找树的UML描述
  • addElement操做
  • removeElement操做
    html

  • 用有序列表实现二叉查找树体现了树为其余集合提供高效实现的用途
  • 有序列表的链表实现分析和二叉查找树实现分析
    java

  • 若是二叉查找树不平衡,其效率可能比线型结构的还要低。能够经过左旋、右旋、左右旋、右左旋解让树平衡化
  • 左旋
    git

  • 右旋
    面试

  • 左右旋
    算法

  • 右左旋
    编程

  • AVL树是树的一种变体,对于树中的每一个节点咱们都会跟踪记录其左右子树的高度,对于书中任何结点若是其平衡因子(即右子树高度减去左子树高度)——大于1或者小于-1,则以该节点为树根的子树须要从新平衡。
  • 树(或树的任何子树)只有两种途径能变得不平衡:插入节点或删除节点
  • AVL树的右旋
    数组

  • AVL树的右左旋
    数据结构

  • 二叉查找树的另外一种实现是红黑树,红黑树是一种平衡二叉查找树,其中每一个节点存储一种颜色(红色或黑色,一般用一个布尔值来实现,值false等价于红色)。控制节点颜色的规则以下ide

    一、每一个结点或是红色的,或是黑色的
    二、根节点是黑色的
    三、每一个叶结点(NIL)是黑色的
    四、若是一个节点是红色的,则它的两个儿子都是黑色的。
    五、对于每一个结点,从该结点到其叶子结点构成的全部路径上的黑结点个数相同。性能

  • 某种程度上,红黑树中的平衡限制没有AVL树那么严格。可是,它的序仍然是logn。
  • 红黑树示意图以下:

教材学习中的问题和解决过程

  • 问题1:AVL树与红黑树之间的联系与区别在哪
  • 问题1解决方案:
  • 红黑树与AVL树的比较:

1.AVL是严格的平衡树,所以在增长或者删除节点的时候,根据不一样状况,旋转的次数比红黑树要多;
2.红黑树是用非严格的平衡来换取增删节点时候旋转次数;
3.因此若是你的应用中,搜索的次数远远大于插入和删除,那么选择AVL树,若是搜索,插入删除次数几乎差很少,应选择红黑树。即,有时仅为了排序(创建-遍历-删除),不查找或查找次数不多,R-B树合算一些。
4.红黑树与AVL树的调整平衡的实现机制不一样,AVL靠平衡因子和旋转,红黑树靠节点颜色以及一些约定再加上旋转。所以,存在去掉颜色的红黑树后它不是AVL树,好比左子树都是黑的,右子树都是红黑相间的,这样整个树高度2n的时候,根节点的左右层数差能够到n。

  • 红黑树(RB-tree)比AVL树的优点在哪?

    红黑是用非严格的平衡来换取增删节点时候旋转次数的下降,任何不平衡都会在三次旋转以内解决,而AVL是严格平衡树,所以在增长或者删除节点的时候,根据不一样状况,旋转的次数比红黑树要多。因此红黑树的插入效率更高。红黑树可以以O(log2 n) 的时间复杂度进行搜索、插入、删除操做。红黑树的算法时间复杂度和AVL相同,但统计性能比AVL树更高。所以,若是你的业务中查找远远多于插入、删除,那选AVL树;若是查找、插入、删除频率差很少,那么选择红黑树。

  • 问题2:没法理解课本上给出的红黑树的插入操做

  • 问题2解决方案:查阅资料总结以下

    插入过程

默认插入的结点为红色。为什么?
由于红黑树中黑节点至少是红节点的两倍,所以插入节点的父节点为黑色的几率较大,而此时并不须要做任何调整,所以效率较高。

1. 父为黑

插入后无需任何操做。因为黑节点个数至少为红节点的两倍,所以父为黑的状况较多,而这种状况在插入后无需任何调整,这就是红黑树比AVL树插入效率高的缘由!

2. 父为红

父为红的状况破坏了红黑树的性质,此时须要根据叔叔的颜色来作不一样的处理。

1.叔叔为红

此时很简单,只需交换爸爸、叔叔和爷爷的颜色便可。
此时若爷爷节点和太爷爷节点颜色相同,再以爷爷节点为起始节点,进行刚才相同的操做,即:根据爷爷的兄弟颜色作相应的操做。
2.叔叔为黑
此时较为复杂,分以下四种状况:
a)爸爸在左、叔叔在右、我在左

以爸爸为根节点,进行一次R旋转。 
b)爸爸在左、叔叔在右、我在右

先以我为根节点,进行一次L旋转;
再以我为根节点,进行一次R旋转。
c)叔叔在左、爸爸在右、我在左

先以我为根节点,进行一次R旋转;
再以我为根节点,进行一次L旋转
d)叔叔在左、爸爸在右、我在右

以爸爸为根节点,进行一次L旋转。

代码调试中的问题和解决过程

  • 问题1:链式二叉查找树中findMax方法运行时出现空指针异常
    运行截图以下:

方法代码及报错位置截图以下:

  • 问题1解决方案:通过debug调试发现是逻辑错误问题,经过与findMin方法对比改正后代码以下:
//返回二叉查找树中的最大元素
    @Override
    public T findMax() {
        T result = null;

        if (isEmpty())
            throw new EmptyCollectionException("LinkedBinarySearchTree");
        else {
            if (root.getRight() == null) {
                result = root.getElement();
            } else {
                BinaryTreeNode<T> current = root.getRight();
                while (current.getRight() != null) {
                    current = current.getRight();
                }
                result = current.getElement();
            }
        }
        return result;
    }
}

代码托管

上周考试错题总结

上周无错题!!!

结对及互评

  • 本周结对学习状况
    本周主要二叉查找树进行了较为深刻的学习,在对链式二叉查找树学习时问题很少,可是当学到了AVL树时就遇到了较大的麻烦,问题多了起来,可是经过查阅资料以及与结对伙伴的讨论,最终使问题获得了较好的解决,经过结对编程,咱们的学习效率获得了明显提高,但愿之后更加默契,共同努力,使本身的编程能力获得更大的提升!

感想

乐观向上!灵活变通!永不言弃!坚持努力!

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 0/0 1/1 4/4
第二周 464/464 1/2 10/14 理解掌握了用数组和链表实现栈的方法
第三周 494/958 1/3 10/24 理解掌握了用数组和链表实现队列的方法
第四周 1629/2587 2/5 20/44 对用链表和数组实现列表进行了学习
第五周 856/3443 2/7 15/59 较为深刻的学习了查找和排序方法的实现
第六周 668/4111 1/8 20/79 学习了链式二叉树的实现
第七周 900/5011 1/9 15/99 对二叉查找树进行了较为深刻的学习
  • 计划学习时间:20小时

  • 实际学习时间:15小时

  • 改进状况:在从此的学习中遇到问题,首先要本身努力解决,若是没有思路,不能一直钻牛角尖,要学会 查阅资料,吸收别人的经验,学会扬弃,从而提升本身的学习效率。

参考资料

相关文章
相关标签/搜索