zoukankan      html  css  js  c++  java
  • 20172330 2018-2019-1 《程序设计与数据结构》第七周学习总结

    20172330 2018-2019-1 《程序设计与数据结构》第七周学习总结

    教材学习内容总结

    二叉查找树


    在二叉查找树中:

    • 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
    • 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
    • 叶节点的左、右子树也分别为二叉查找树。
    • 没有键值相等的节点。

    插入删除

    与次优二叉树相对,二叉排序树是一种动态树表。其特点是:树的结构通常不是一次生成的,而是在查找过程中,当树中不存在关键字等于给定值的结点时再进行插入。新插入的结点一定是一个新添加的叶子结点,并且是查找不成功时查找路径上访问的最后一个结点的左孩子或右孩子结点。

    • 1.首先执行查找算法,找出被插结点的父亲结点。
      判断被插结点是其父亲结点的左、右儿子。将被插结点作为叶子结点插入。
      若二叉树为空。则首先单独生成根结点。首先执行查找算法,找出被插结点的父亲结点。
      判断被插结点是其父亲结点的左、右儿子。将被插结点作为叶子结点插入。
      若二叉树为空。则首先单独生成根结点。

    • 2.执行删除结点算法
      在二叉排序树删去一个结点,分三种情况讨论:
      1.若结点为叶子结点,即左子树和右子树均为空树。由于删去叶子结点不破坏整棵树的结构,则可以直接删除此子结点。
      2.若结点只有左子树或右子树,此时只要令或直接成为其双亲结点的左子树或右子树即可,作此修改也不破坏二叉排序树的特性。
      3.若结点的左子树和右子树均不空。在删去结点之后,为保持其它元素之间的相对位置不变,可按中序遍历保持有序进行调整,可以:
      令结点的直接前驱(或直接后继)替代该结点,然后再从二叉排序树中删去它的直接前驱(或直接后继)即让结点的左子树(如果有的话)成为结点左子树的最左下结点(如果有的话),再让左子树成为结点的左右结点的父结点。

    平衡二叉查找树

    平衡二叉查找树是带有平衡条件的二叉查找树。平衡条件:每个节点的左子树和右子树的高度差最多为1二叉查找树(其中空树的高度为-1)
    思想:
    向平衡二叉树中插入一个新结点后破坏了平衡二叉树的平衡性。首先要找出插入新结点后失去平衡的最小子树根结点的指针。然后再调整这个子树中有关结点之间的链接关系,使之成为新的平衡子树。当失去平衡的最小子树被调整为平衡子树后,原有其他所有不平衡子树无需调整,整个二叉排序树就又成为一棵平衡二叉树。

    AVL树

    • AVL树的旋转规律:
      AVL树的基本操作一般涉及运做同在不平衡的二叉查找树所运做的同样的算法。但是要进行预先或随后做一次或多次所谓的"AVL旋转"。

    假设由于在二叉排序树上插入结点而失去平衡的最小子树根结点的指针为a(即a是离插入点最近,且平衡因子绝对值超过1的祖先结点),则失去平衡后进行进行的规律可归纳为下列四种情况:

    1. LL型
      平衡二叉树某一节点的左孩子的左子树上插入一个新的节点,使得该节点不再平衡。这时只需要把树向右旋转一次即可,如图所示,原A的左孩子B变为父结点,A变为其右孩子,而原B的右子树变为A的左子树,注意旋转之后Brh是A的左子树(图上忘在A于Brh之间标实线)

    2. RR型
      平衡二叉树某一节点的右孩子的右子树上插入一个新的节点,使得该节点不再平衡。这时只需要把树向左旋转一次即可,如图所示,原A右孩子B变为父结点,A变为其左孩子,而原B的左子树Blh将变为A的右子树。

    3. LR型
      平衡二叉树某一节点的左孩子的右子树上插入一个新的节点,使得该节点不再平衡。这时需要旋转两次,仅一次的旋转是不能够使二叉树再次平衡。如图所示,在B节点按照RR型向左旋转一次之后,二叉树在A节点仍然不能保持平衡,这时还需要再向右旋转一次。

    4. RL型
      平衡二叉树某一节点的右孩子的左子树上插入一个新的节点,使得该节点不再平衡。同样,这时需要旋转两次,旋转方向刚好同LR型相反。

    红黑树

    • 1.红黑树是在普通二叉树上,对没个节点添加一个颜色属性形成的,同时整个红黑二叉树需要同时满足一下五条性质
      红黑树需要满足的五条性质:
      性质一:节点是红色或者是黑色;
      在树里面的节点不是红色的就是黑色的,没有其他颜色,要不怎么叫红黑树呢,是吧。
      性质二:根节点是黑色;
      根节点总是黑色的。它不能为红。
      性质三:每个叶节点(NIL或空节点)是黑色;

      性质四:每个红色节点的两个子节点都是黑色的(也就是说不存在两个连续的红色节点);
      就是连续的两个节点不能是连续的红色,连续的两个节点的意思就是父节点与子节点不能是连续的红色。
      性质五:从任一节点到其没个叶节点的所有路径都包含相同数目的黑色节点;

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

    • 问题1:二叉查找树如何添加元素?
    • 问题1解决方案:首先我们需要了解二叉树中元素是如何放置的。我们定义一个根的元素,然后把新加进来的元素和根比较(以第二个加进来的元素为10,根为20举例)。10<20,所以我们将10放在根的左结点,由于根的左子树目前只有一个元素所以我们将10设置为根的左子树的根。如果第三个元素是11,那么我们首先和根比较,小于20,那么我们将11往下放,与10比较,比10大,那么我们放在10的右结点上。(如果添加的元素比20小也比10小那么放在10的左结点)以此类推。右子树也是一样的道理。总的来说,二叉树的元素放置是以根为基准,比根大的放右子树,比根小的放左子树。如果一样的话左右子树任君挑选。
    • 问题2:红黑树的元素查找
    • 问题2解决方案

    1、当插入的节点是根节点时,直接涂黑即可;
    2、当要插入的节点的父节点是黑色的时候。
    3、如果要插入的节点的父节点是红色且父节点是祖父节点的左支的时候。
    这个要分两种情况,一种是叔叔节点为黑的情况,一种是叔叔节点为红的情况。
    当叔叔为黑时,也分为两种情况,一种是要插入的节点是父节点的左支,另一种是要插入的节点是父亲的右支。
    我们先看一下当要插入的节点是父节点的左支的情况:

    这个时候违反了性质四,我们就需要进行调整操作,使之符合性质四,我们可以通过对祖父节点进行右旋同时将祖父节点和父节点的颜色进行互换,这样就变成了:

    经过这样的调整可以符合性质四并且不对其他性质产生破坏。
    当插入的节点是父节点的右支的时候:

    当要插入的节点是父节点的右支的时候,我们可以先对父节点进行左旋,变成如下:

    如果我们把原先的父节点看做是新的要插入的节点,把原先要插入的节点看做是新的父节点,那就变成了当要插入的节点在父节点的左支的情况,对,是的,就是按照当要插入的节点在父节点的左支的情况进行旋转,旋转完之后变成如下:

    4、如果要插入的节点的父节点是红色且父节点是祖父节点的右支的时候;
    这个时候的情况跟情况3所表述的情况是一个镜像,将情况3的左和右互换一下就可以了。
    5、如果要插入的节点的父节点是红色并且叔叔节点也为红色,如下:

    这个时候,只需将父亲节点和叔叔节点涂黑,将祖父节点涂红。

    以上就是插入的全部过程。

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

    • 问题1:在编写树的方法时,RemoveFirst方法一直报错
    • 问题1解决方案:在检查后发现是在ListADT时没有写进去导致出现了错误。

    代码托管

    上周考试错题总结

    结对及互评

    • 基于评分标准,我给严域俊的博客打分:7分。得分情况如下:

    正确使用Markdown语法(加1分)

    模板中的要素齐全(加1分)

    教材学习中的问题和解决过程, (加3分)

    感想,体会真切的(加1分)

    点评认真,能指出博客和代码中的问题的(加1分)

    • 博客中值得学习的或问题:
      • 图片和文字相结合,方便理解。
      • 增加了博客中的目录,方便查看,同时样式进行了更新,显得更加美观
      • 阅读了许多资料,使得博客更有说服力。
    • 代码中值得学习的或问题:
      - commit依旧很详细,有条理性。

    点评过的同学博客和代码

    • 本周结对学习情况
      • 20172333
      • 结对学习内容
        教材第11章,运行教材上的代码
        完成课后自测题,并参考答案学习
        完成课后自测题,并参考答案学习
        完成程序设计项目:至少完成PP11.3、PP11.8

    其他(感悟、思考等,可选)

    这一周花了点心思在这一章上面,也好好阅读了很多内容,掌握的还算可以。

    学习进度条

    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
    目标 5000行 30篇 400小时
    第一周 0/0 1/1 10/10
    第二周 700/700 1/2 10/20
    第三周 700/1400 1/3 10/30
    第四周 500/1900 2/5 10/40
    第五周 569/2469 1/6 10/50
    第六周 1070/3539 1/7 10/60
    第七周 1070/3539 1/8 10/70

    参考:软件工程软件的估计为什么这么难软件工程 估计方法

    • 计划学习时间:10小时

    • 实际学习时间:10小时

    参考资料

  • 相关阅读:
    ZOJ 3327 Friend Number
    ZOJ 3324 Machine
    2010-2011 ACM-ICPC, NEERC, Southern Subregional Contest C Explode 'Em All
    UVA 12594 Naming Babies
    POJ 3709 K-Anonymous Sequence
    POJ 1180 Batch Scheduling
    POJ 1160 Post Office
    HDU 3516 Tree Construction
    HDU 3045 Picnic Cows
    UVALive 5097 Cross the Wall
  • 原文地址:https://www.cnblogs.com/linanlalala/p/9898303.html
Copyright © 2011-2022 走看看