20182333 2019-2020-1 《数据结构与面向对象程序设计》第九周学习总结
教材学习内容总结
第十六章 树
树
1.树是非线性结构,其元素组织为一个层次结构
- 2.树的度表示树中的任意结点的最大子结点数
- 3.有m个元素的平衡n叉树的高度是lognm
- 4.树的遍历有4种方法
- 5.进行层序遍历时可采用队列来储存树中的元素
- 6.使用数组实现二叉树时,位于位置n的元素的左孩子在(2n+1)的位置,其右孩子在(2*(n+1))的位置
- 7.树的基于数组的存储链实现方式可以占数组中的连续位置,不管树是不是完全树
- 8.如何在一般二叉树中添加及删除元素,要取决于树的用途
9.使用决策树可以设计专家系统
二叉树
- 1.二叉查找树时一颗二叉树,对于其中的每个结点,左子树上的元素小于父结点的值,二右子树上的元素大于等于父结点的值
- 2.如果没有其他的操作,二叉查找树的树形由元素的添加次序来决定
- 3.最有效地二叉查找树时平衡的,所以每次比较时可以排除一半的元素
- 4.当从二叉查找树中删除元素时要考虑三种情形,其中的两种比较简单
- 5.当从二叉查找树中删除有两个子结点的结点时,比较好的办法是用它的中序后继来取代它
- 6.可以对二叉查找树进行旋转以恢复平衡
部分计算公式
- 1.二叉树上第i层上的结点数目最多为2^(i-1)(i>=1)
- 2.深度为k的二叉树至多有2^k-1个结点(i>=1)
- 3.包含n个结点的二叉树的高度至少为log2(n+1)
- 4.在任意一棵二叉树中,若终端结点的个数为n0,度为2的结点数为n2,则n0=n2+1.
第十七章 二叉查找树
二叉查找树
在二叉查找树中:
若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 叶节点的左、右子树也分别为二叉查找树。 没有键值相等的节点。
插入删除
与次优二叉树相对,二叉排序树是一种动态树表。其特点是:树的结构通常不是一次生成的,而是在查找过程中,当树中不存在关键字等于给定值的结点时再进行插入。新插入的结点一定是一个新添加的叶子结点,并且是查找不成功时查找路径上访问的最后一个结点的左孩子或右孩子结点。
1.首先执行查找算法,找出被插结点的父亲结点。
判断被插结点是其父亲结点的左、右儿子。将被插结点作为叶子结点插入。
若二叉树为空。则首先单独生成根结点。首先执行查找算法,找出被插结点的父亲结点。
判断被插结点是其父亲结点的左、右儿子。将被插结点作为叶子结点插入。
若二叉树为空。则首先单独生成根结点。
2.执行删除结点算法
在二叉排序树删去一个结点,分三种情况讨论:
1.若结点为叶子结点,即左子树和右子树均为空树。由于删去叶子结点不破坏整棵树的结构,则可以直接删除此子结点。
2.若结点只有左子树或右子树,此时只要令或直接成为其双亲结点的左子树或右子树即可,作此修改也不破坏二叉排序树的特性。
3.若结点的左子树和右子树均不空。在删去结点之后,为保持其它元素之间的相对位置不变,可按中序遍历保持有序进行调整,可以令结点的直接前驱(或直接后继)替代该结点,然后再从二叉排序树中删去它的直接前驱(或直接后继)即让结点的左子树(如果有的话)成为结点左子树的最左下结点(如果有的话),再让左子树成为结点的左右结点的父结点。
平衡二叉查找树
- 1.平衡二叉查找树是带有平衡条件的二叉查找树。
- 2.平衡条件:每个节点的左子树和右子树的高度差最多为1二叉查找树(其中空树的高度为-1)
- 3.思想:向平衡二叉树中插入一个新结点后破坏了平衡二叉树的平衡性。首先要找出插入新结点后失去平衡的最小子树根结点的指针。然后再调整这个子树中有关结点之间的链接关系,使之成为新的平衡子树。当失去平衡的最小子树被调整为平衡子树后,原有其他所有不平衡子树无需调整,整个二叉排序树就又成为一棵平衡二叉树。
4.右旋转
如果由根的左子结点的左子树上的长路径而带来的不平衡性。将执行步骤: 令根的左子结点变为新的根。 令原根结点变为新的根结点的右子结点。 令原根的左子结点的右子结点变为原根的结点的新的左子结点。
5.左旋转
如果由根的右子结点的右子树上的长路径而带来的不平衡性。将执行步骤: 令根的右子结点变为新的根。 令原根结点变为新的根结点的左子结点。 令原根的右子结点的左子结点变为原根的结点的新的右子结点。
6.右-左旋转
如果不平衡性是由根的右子结点的左子树中的长路径引发的,则必须先绕那个异常子树执行一次右旋转,然后再绕跟执行一次左旋转。7.左-右旋转
如果不平衡性是由根的左子结点的右子树中的长路径引发的,则必须先绕那个异常子树执行一次左旋转,然后再绕跟执行一次右旋转。
教材学习中的问题和解决过程
- 问题1:树的遍历
问题1解决方案:
1、先序遍历——先访问根,再自左向右遍历子树
2、中序遍历——遍历左子树,然后访问根,然后自左向右遍历余下的各个子树
3、后续遍历——自左向右遍历各个子树,然后访问根
4、层序遍历——从树的顶层(根)打包底层,从左至右,访问树中每层的每个结点
- 问题2:满二叉树和完全二叉树的区别
问题2解决方案:
满二叉树——除了叶结点外每一个结点都有左右子叶且叶子结点都处在最底层的二叉树。
完全二叉树——若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。
满二叉树一定是完全二叉树,完全二叉树不一定是满二叉树。
- 问题3:二叉查找树如何添加元素?
问题3解决方案:首先我们需要了解二叉树中元素是如何放置的。我们定义一个根的元素,然后把新加进来的元素和根比较(以第二个加进来的元素为10,根为20举例)。10<20,所以我们将10放在根的左结点,由于根的左子树目前只有一个元素所以我们将10设置为根的左子树的根。如果第三个元素是11,那么我们首先和根比较,小于20,那么我们将11往下放,与10比较,比10大,那么我们放在10的右结点上。(如果添加的元素比20小也比10小那么放在10的左结点)以此类推。右子树也是一样的道理。总的来说,二叉树的元素放置是以根为基准,比根大的放右子树,比根小的放左子树。如果一样的话左右子树任君挑选。
- 问题4:为什么二叉查找树的平衡性非常重要?
问题4解决方案:如果二叉查找树是平衡的,每次比较时都会排除差不多一半的元素。树越不平衡,它离线性结构越近,效率也就越低。
代码调试中的问题和解决过程
- 问题1:
问题1解决方案:
- 问题2:
问题2解决方案:
代码托管
上周考试错题总结
上周没有考试,所以没有错题。
点评过的同学博客和代码
其他(感悟、思考等,可选)
本周主要学习了树和二叉查找树。学到了许多重要的知识,例如四种遍历、三种表达式、关于树的问题的一些计算、二叉查找树的平衡因子等等,收获颇多。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 10000行 | 30篇 | 400小时 | |
第一周 | 56/56 | 2/2 | 20/20 | 主要学会了简单的操作Linux以及如何编写简单的java程序并将它上传到码云 |
第二、三周 | 331/407 | 3/5 | 23/43 | 学会了一些类和程序包的使用,也明白了C语言和Java在有些地方的区别 |
第四周 | 595/1002 | 2/7 | 20/60 | 学会了IDEA以及用IDEAgit码云,也学会了TDD测试 |
第五周 | 1621/2623 | 2/9 | 17/77 | 见识了服务器与用户链接的代码,也学习了继承的一些知识。 |
第六周 | 1770/4393 | 1/10 | 22/99 | 学习了多态以及与接口和继承的关系,还有就是对异常的学习和处理异常的方法以及自定义一个异常 |
第七周 | 1747/6140 | 3/13 | 23/122 | 学习了渐进复杂度的计算,栈和队列的学习,分别用数组和链表实现队列 |
第八周 | 384/6524 | 1/14 | 20/142 | 学习了一些查找和排序的算法,也学会了计算ASL |
第九周 | 1895/8419 | 3/17 | 22/164 | 学习了树的四种遍历,和怎样根据已知序列求未知序列等等 |
计划学习时间:20小时
实际学习时间:22小时
改进情况:无