第九周
学号 2019-2020-20182321 《数据结构与面向对象程序设计》第八周学习总结
教材学习内容总结
- 树与前面的栈、队列还有链表不同,树是一个非线性集合。
- 树的构成元素有边和节点,节点里储存着树的内容,边是各个节点之间的连接,可以让我们从树的一个节点访问到另一个节点。
- 树(英语:tree)是一种抽象数据类型或是实现这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。它是由n(n>0)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的
- 树有以下的特点:
①每个节点有零个或多个子节点;
②没有父节点的节点称为根节点;
③每一个非根节点有且只有一个父节点;
④除了根节点外,每个子节点可以分为多个不相交的子树;
![](https://img2018.cnblogs.com/blog/1779734/201911/1779734-20191118230009071-1217233291.jpg)
- 实现树的方法有数组和链表两个方法,数组是运用了父亲节点和其子节点之间的序号关系来进行构建数,而链表方法其实只是在一个节点中增加多个引用,使其可以扩展、分支。
- 数的遍历方法有中序遍历、前序遍历、后序遍历三种
- 运用二叉树表示决策树,其实只是在每个二叉树的节点里存储一个字符换元素,然后根据决策者的Yes或者no来进行决策。
- 二叉查找树的一个特性是,比其节点小的数会再节点的左子树处,比节点大的数 会在节点的右子数处
- 树的基本术语:
节点的度:节点拥有的子树的数目。
叶子:度为零的节点。
分支节点:度不为零的节点。
树的度:树中节点的最大的度。
层次:根节点的层次为1,其余节点的层次等于该节点的双亲的层次加1。
树的高度:树中节点的最大层次。
无序树:如果树中节点的各子树之间的次序是不重要的,可以交换位置。
有序树:如果树中节点的各子树之间的次序是重要的,不可以交换位置。
森林:0个或多个不相交的树组成。对森林加上一个根,森林就成了树。删去根,树就成了森林。
- 除了二叉查找树还有满二叉树以及完全二叉树
- 平衡二叉搜索树(英语:Balanced Binary Tree)是一种结构平衡的二叉搜索树,即叶节点高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树
-二叉查找树还有可以左旋转和右-左旋转、左-右旋转、右旋转。 具体如下图
教材中遇到的问题和解决过程
- 问题1:什么是前序遍历、中序遍历、后序遍历
- 问题1解决方法:
1.前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树。
若二叉树为空则结束返回,否则:
(1)访问根结点。
(2)前序遍历左子树。
(3)前序遍历右子树 。前序遍历前序遍历
需要注意的是:遍历左右子树时仍然采用前序遍历方法。
如下图
前序遍历结果:ABDECF(我们在知道后序遍历和中序遍历的结果时也可以知道前序遍历)
2.中序遍历(LDR)是二叉树遍历的一种,也叫做中根遍历、中序周游。在二叉树中,先左后根再右。巧记:左根右。
中序遍历首先遍历左子树,然后访问根结点,最后遍历右子树若二叉树为空则结束返回,
否则:
(1)中序遍历左子树
(2)访问根结点
(3)中序遍历右子树
如下图
中序遍历结果:DBEAFC
3.后序遍历(LRD)是二叉树遍历的一种,也叫做后根遍历、后序周游,可记做左右根。后序遍历有递归算法和非递归算法两种。在二叉树中,先左后右再根。巧记:左右根。
后序遍历首先遍历左子树,然后遍历右子树,最后访问根结点,在遍历左、右子树时,仍然先遍历左子树,然后遍历右子树,最后遍历根结点。即:
若二叉树为空则结束返回,
否则:
(1)后序遍历左子树
(2)后序遍历右子树
(3)访问根结点
如下图
后序遍历结果:DEBFCA(已知前序遍历和中序遍历,就能确定后序遍历。)
- 问题2:满二叉树和完全二叉树的区别
- 问题2解决方法:
1.满二叉树定义:高度为h,并且有2^h-1个节点的二叉树,叫做满二叉树。
2.完全二叉树定义:二叉树中,只有最下面两层节点的度可以小于2,并且最下一层的叶节点集中在靠左的若干位置上,这样的二叉树称之为完全二叉树。
二叉树中,只有最下面两层节点的度可以小于2,并且最下一层的叶节点集中在靠左的若干位置上,这样的二叉树称之为完全二叉树。
通过上面我们可以观察到,两个二叉树不同点就是在最后一行的节点处不同,满二叉树是每个节点都满的,而完全二叉树不一定。
- 问题3:何为决策树?
- 问题3解决方法:决策树(Decision Tree)是在已知各种情况发生概率的基础上,通过构成决策树来求取净现值的期望值大于等于零的概率,评价项目风险,判断其可行性的决策分析方法,是直观运用概率分析的一种图解法。由于这种决策分支画成图形很像一棵树的枝干,故称决策树。
如下图(摘自教材)
代码调试中的问题和解决过程
- 问题1:如何用代码实现前序遍历、中序遍历、后序遍历
- 问题1解决方法:根据上面给我们的伪代码思路,我们可以打出下面的前中后序遍历方法代码
前序遍历
public static node creat(node node,String[] s1){
String temp = s1[i++];
if(temp.equals("#")){
return null;
}else{
node = new node(temp);
node.leftchild = creat(node.leftchild,s1);
node.rightchild = creat(node.rightchild,s1);
}
return node;
}
public static void first(node biTree)
{
Stack<node> stack = new Stack<node>();
while(biTree != null || !stack.isEmpty())
{
while(biTree != null)
{
System.out.println(biTree.data+" (前序非递归实现)");
stack.push(biTree);
biTree = biTree.leftchild;
}
if(!stack.isEmpty())
{
biTree = stack.pop();
biTree = biTree.rightchild;
}
}
运行结果为
中序遍历
public static node creat(node node,String[] s1){
String temp = s1[i++];
if(temp.equals("#")){
return null;
}else{
node = new node(temp);
node.leftchild = creat(node.leftchild,s1);
node.rightchild = creat(node.rightchild,s1);
}
return node;
}
public static void midRe(node biTree)
{
if(biTree == null)
return;
else
{
midRe(biTree.leftchild);
System.out.println(biTree.data+" (中序递归)");
midRe(biTree.rightchild);
}
}
后序遍历
public static node creat(node node,String[] s1){
String temp = s1[i++];
if(temp.equals("#")){
return null;
}else{
node = new node(temp);
node.leftchild = creat(node.leftchild,s1);
node.rightchild = creat(node.rightchild,s1);
}
return node;
}
public static void back(node biTree)
{
if(biTree == null)
return;
else
{
back(biTree.leftchild);
back(biTree.rightchild);
System.out.println(biTree.data+" (后序遍历)");
}
}
运行结果
- 问题2:如何层序遍历输出二叉树
- 问题2解决方法:
这里我想到的是利用数组来将二叉树层序输出。
如下图
按照二叉树的节点序号的规律,将二叉树节点内的值赋值给数组,一个节点的左子树是它的序号2i+1,它的右子树是它的2i+2,赋值好了以后再一次性将其全部输出就行了。下面是我的一部分代码
String s = "A B # C D # # # E # F # #";
String[] a =s.split("\\s");
node root = new node();
root = creat(root,a);
node[] tree = new node[15];
tree[0] = root;
for(int i=1;i<tree.length;i++)
{
tree[i] = new node("#");
}
for(int i =0;i<15;i++)
{
if(i<15&&tree[i].leftchild!=null)
tree[i*2+1]=tree[i].leftchild;
if(i<15&&tree[i].rightchild!=null)
tree[i*2+2]=tree[i].rightchild;
}
代码托管
(statistics.sh脚本的运行结果截图)
上周考试错题总结
- 错题:In removing an element from a binary search tree, another node must be ___________ to replace the node being removed.
A.duplicated
B.demoted
C.promoted
D.None of the above
解析:覆盖删除节点的节点必须是前驱节点,这里是我的疏忽大意。正确选C。
2. 错题:A binary search tree is a binary tree with the added property that the left child is greater than the parent, which is less than or equal to the right child.
A.True
B.Flase
解析:右边的子树一定要小于右边的子树,这题是看错了
3. In removing an element from a binary search tree, another node must be demoted to replace the node being removed.
A.True
B.Flase
解析:不一定,删除的情况有三种,所以这句话是错的。
- To maintain the completeness of the tree, there is only one valid element to replace the root, and that is the element stored in the first leaf in the tree.
A.True
B.Flase
解析:不一定是树的第一个叶子中的元素,应该是其前驱节点。
- 上周博客互评情况
- 20182334
- 结对照片
其他(感悟、思考等,可选)
其实我也不知道这周为什么我的代码会突然激增那么多........但是学习二叉树属实让我费力了不少,还会经常出现节点的左右树枝被砍断的情况,只能一步一步的debug来调整。
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 200/200 | 2/2 | 20/20 | |
第二周 | 300/500 | 2/4 | 18/38 | |
第三周 | 623/1000 | 3/7 | 22/60 | |
第四周 | 600/1600 | 2/9 | 22/82 | |
第五周 | 1552/2987 | 2/11 | 22/94 | |
第六周 | 892/3879 | 2/11 | 22/114 | |
第七周 | 2284/6163 | 2/13 | 22/134 | |
第八周 | 2284/6163 | 2/13 | 22/134 | |
第九周 | 24118/30281 | 3/16 | 40/174 | |
参考:软件工程软件的估计为什么这么难,软件工程 估计方法 |
-
计划学习时间:10小时
-
实际学习时间:40小时
-
改进情况:
(有空多看看现代软件工程 课件
软件工程师能力自我评价表)