学无止境,但愿本身能够坚持下去,就算本身有太多的事情也不但愿本身落下学习,也但愿本身能够活成本身想要的样子!!加油吧!❤️php
1、概述html
一、什么是树:树是一种非线性结构,其中的元素被组织成一个层次结构。java
二、树的组成部分:树由一个包含结点和边的集构成,其中的元素被存储在这些结点中,边则将一个结点和另个结点链接起来。每一结点都位于该树层次中的某些特定层上。树的根就是那个位于该树顶层的惟一结点。(注:一棵树只有一个根结点。)node
三、位于树中叫底层的结点是上一层结点的孩子。git
四、一个结点只有一个双亲,可是一个结点能够有多个孩子。web
五、同一双亲的两个结点称为兄弟。
算法
六、根结点是树中惟一一个没有双亲的结点。没有任何孩子的结点称为叶子。一个至少有一个孩其实自某一特定结点的路径能够子的非根结点称为一个内部结点。数组
七、沿着起始自某一特定结点的路径能够到达的结点是该结点的子孙。数据结构
八、结点的层也就是从根结点到该结点的长度。经过计算从根到该结点所必须越过的边数目,就能够肯定其路径长度。
函数
2、树的分类
一、对结点所含有的孩子数目无限制的树称为广义树。
二、咱们将每一结点限制为不超过n个孩子的树称为一颗n元树。
三、结点最多具备两个孩子的树称为二叉树。(注:含有m个元素的平衡n元树具备的高度为lognm。所以一颗含有n个结点的平衡二叉树具备的高度为log2m)
2、实现树的策略
一、树的数组实现之计算策略:
二、树的数组实现之模拟连接策略
模拟了操做系统管理内存的方式。按照先来先服务的基准连续分配数组位置,而不是经过其在树中的定位将数元素指派到数组位置上。
三、树的分析
(1)树是实现其余集合的有用并且有效的方式。
(2)通常而言,一颗含有m个元素的平衡n元树具备的高度为lognm。
3、树的遍历
一、前序遍历(preorder traversal)
(1)顺序:从根结点开始,访问每一结点机及其孩子。
(2)图解:
二、中序遍历(inorder traversal)
(1)顺序:从根结点开始,访问结点的左孩子,而后是该结点,再而后是任何剩余结点。
(2)图解:
三、后序遍历(postorder traversal)
(1)从根结点开始,访问结点的孩子,而后是该结点。
(2)图解:
四、层序遍历(lever-order traversal)
(1)从根结点开始,访问每一层全部的结点,一次一层。
(2)图解:
4、二叉树
操做 | 描述 |
---|---|
getRoot | 返回指向二叉树根的引用 |
isEmpty | 断定该树是否为空 |
size | 断定树中数量 |
contains | 断定指针目标是否在该树中 |
find | 若是找到该指定元素,则返回指向其的引用 |
toString | 返回树的字符串表示 |
iteratorInOrder | 为树的中序遍历返回一个迭代器 |
iteratorPreOrder | 为树的前序遍历返回一个迭代器 |
iteratorPostOrder | 为树的后序遍历返回一个迭代器 |
iteratorLeverOrder | 为树的层序遍历返回一个迭代器 |
二、用链表实现二叉树
(1)性质1:在二叉树的第 i 层上至多有 2^(i-1)个结点 (i >=1)
(2)性质2:深度为 k 的二叉树至多有2^k -1个结点(k>=1)
(3)性质3:对任何一棵二叉树 T ,若是其终端结点数位n0,度为2的结点数位n2,则n0=n2+1。
注:
(1) n = n0 + n1 + n2 (结点总数 等于 度为0 加 度为1 加 度为2)
(2) n = n0 + 2*n2 +1(n = 分支总数+1 ;分支总数 = n1+n2 (分支是由度为1,度为2的结点射出的))
(3)-(1)得: n0 = n2 + 1
最后一层除外,在最后一层中的结点必须是最左边的结点。
一开始我并无特别理解这个意思是什么,由于个人第一意识就是我以为最后一层都除外了,还提最后一层作什么?
问题1解决方案:
在昨天听了老师讲的课之后就知道他所说的是倒数第二层的结点必须是最左边的结点,这里也就引进了平衡树的概念。
那什么是平衡树呢?
一、平衡树:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,而且左右两个子树都是一棵平衡二叉树。
二、性质:最小二叉平衡树的节点的公式以下 F(n)=F(n-1)+F(n-2)+1
public boolean isOperator() { return (termType == 1); }
它的实如今下面
if (temp.isOperator()) { operand1 = evaluateNode(root.getLeft()); operand2 = evaluateNode(root.getRight()); result = computeTerm(temp.getOperator(), operand1, operand2); } else result = temp.getValue(); }
就是temp究竟是一个什么类型的值,它如何左右与1和其余之间字符?
问题2解决方法:
对于我本身是这样理解的:首先temp.isOperator()
这句的做用就是在判断temp是不是一个操做符,我本身以为termType == 1
只是一个媒介,不管它是不是1都无所谓,那个1只是用于判断是否为一个数字,假如不为一个数字,就判断其为一个操做符,假如是操做数的话,就进行继续递归,继续重复。
问题3解决方法:
(1)首先咱们从打的包中看到了咱们这个方法中用到了四个类,包括以前写过的一个和本章须要完善的三个,以下
import chapter10.jsjf.BinaryTreeNode; import chapter10.jsjf.LinkedBinaryTree; import chapter6.练习题.pp6_8.ArrayUnorderedList; import chapter6.练习题.pp6_8.UnorderedListADT;
(2)其次咱们先要了解整个输出的过程,假如要输出一棵树的话,就得有它的形状,即如何控制咱们所须要的空格,在我本身的计算中,和书中进行了统一,假如一棵树的层数有k层的话,就是在第0层第一个元素以前有2^k个空格" ";
而后当咱们判断输出第0层了之后就经过1个或者2个\n进行换行,(ps:两个会好看一点,就和书中代码同样),进行判断就须要咱们将元素和字符分别存入两个链表中,由于在我bug的时候发现一个问题,就是常常作的一个操做就是将链表进行头删,返回头删的值,这一操做为的是返回删除的值进行比较,选择是否进入判断语句。而后换行之后,进行一样的空格,假如遇到元素就要开始进行输出,转至(3)。进行新的空格计算,也就是2^(k-1),这个空格间距就是两个元素之间的空格数目。重复上述过程。
countNodes = countNodes + 1; current = nodes.removeFirst(); currentLevel = levelList.removeFirst(); if (currentLevel > previousLevel) { result = result + "\n\n"; previousLevel = currentLevel; for (int j = 0; j < ((Math.pow(2, (printDepth - currentLevel))) - 1); j++) result = result + " "; } else { for (int i = 0; i < ((Math.pow(2, (printDepth - currentLevel + 1)) - 1)) ; i++) { result = result + " "; } }
(3)输出元素,包括空格和换行符咱们都用一个result
进行保存,之后再转至(2)结尾。
f (current != null) { result = result + (current.getElement()).toString(); nodes.addToRear(current.getLeft()); levelList.addToRear(currentLevel + 1); nodes.addToRear(current.getRight()); levelList.addToRear(currentLevel + 1); } else { nodes.addToRear(null); levelList.addToRear(currentLevel + 1); nodes.addToRear(null); levelList.addToRear(currentLevel + 1); result = result + " "; } }
问题1:在输出表达式树的时候,2和1的位置老是跑偏
我可能花了3个小时一直bug找问题,可是就是找不到
问题1解决:
我忽然意识到可能本身以前写的添加方法不能用或者有错,就回去看了一眼,果然不出我所料。。
ps:以前写的大体是这样的:
就是用了一个while循环,找到最后一个添加进去,最后发现,本身有毒,有个rear不用,老是想着找最后一个,确定是链表敲多了,本身都发现本身被链表已经深深的洗脑🤮🤮🤮
更改之后:
错题1:
There are four basic methods for traversing a tree: preorder, inorder, postorder, and level-order.
A .Top down, bottom up, inorder, and postorder
B .Top down, inorder, postorder, and level-order
C .Bottom up, preorder, in order, and postorder
D .preorder, inorder, postorder, and level-order
正确答案: D 个人答案: B
错因:虽然答案已经显示出来了,可是仍是作错了,我当时对这个题的理解就是去想着那个遍历顺序的方向了,实则没有想到还能把答案写出来。
错题2:
___________ traversal means visit the nodes at each level, one level at at time, starting with the root.
A .preorder
B .postorder
C .inorder
D .level-order
正确答案: D 个人答案: A
错因:我刚刚思考了一下我为何选的是A,多是我当时用了翻译,翻译的让我撒懒,不再相信谷歌翻译了。
代码调试中的问题和解决过程, 一个问题加1分
本周应该是我以为全班以为学习Java第一次不少人都说不懂,因此难说明其重要性,树,的确是一个树,给咱们带来了无穷无尽的生机,天天晚上在熬夜写代码的时候,就以为本身真的在纳凉,都快被冻死了。
虽然本周过的实在不易,可是终究咱们仍是把它抠出来了,虽然仍是有一些问题,可是总比一窍不通好,我看到了如今班里呈现出的学习氛围并无那么强烈了,你们有些人都开始应付做业,应付老师,我以为实则不应,如今享受之后要享受的时光,之后终究是要还回来的,因此,你们加油,共勉!
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | |
---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 |
第一周 | 0/0 | 1/1 | 6/6 |
第二周 | 1313/1313 | 1/2 | 20/26 |
第三周 | 901/2214 | 1/3 | 20/46 |
第四周 | 3635/5849 | 2/4 | 20/66 |
第五周 | 1525/7374 | 1/5 | 20/86 |
第六周 | 1542/8869 | 2/5 | 25/111 |
蓝墨云班课
Java程序设计
数据结构之平衡树(Treap)
二叉树的4种遍历方法图解
二叉树遍历的递归、非递归算法(Java实现)