含有m个元素的平衡n元树具备的高度为lognm。html
对于任何存储在数组位置n处的元素而言,该元素的左结点将存储在位置2n+1处,该元素的右结点将存储在位置2(n+1)处。java
模拟连接策略容许连续分配数组位置而不用考虑该树的彻底性。node
二叉树--表达式树表达式树的及其内部结点包含着操做,且全部叶子也包含着操做数。对操做树的求值是从下往上的。git
二叉树--决策树(背部疼痛诊断器)决策树的结点表示决策点,其子结点表示在该决策点的可选项。决策树的叶结点表示可能的判断,这些推断是根据决策结果得出的。算法
- 满二叉树是指除最后一层外,每一层上的全部结点都有两个子结点。
- 若是一颗满二叉树的深度为d,最大层数为k
- 它的叶子数是: 2^d
- 第k层的节点数是: 2^(k-1)
- 总节点数是: 2^k-1 =>
(1 + 2 + 4 + 8 ··· + 2^(k-1)的和)
,其总节点数必定是奇数。
- 彻底二叉树是指除最后一层外,每一层上的结点数均达到最大值;在最后一层上只缺乏右边的若干结点。
- 彻底二叉树的判断方法:叶节点只能出如今最下层和次下层,而且最下面一层的结点都集中在该层最左边的若干位置的二叉树
- 彻底二叉树的特色是:
- 只容许最后一层有空缺结点且空缺在右边,即叶子结点只能在层次最大的两层上出现。
- 对任一结点,若是其右子树的深度为j,则其左子树的深度必为j或j+1。 即度为1的点只有1个或0个。
(treeStack.peek()).printTree()
是把树的形式从栈treeStack的顶部返回出来,再调用Expreesion类中的printTree方法(最恶心的部分),就成一棵树了。public String printTree() { UnorderedListADT<BinaryTreeNode<ExpressionTreeOp>> nodes = new ArrayUnorderedList<BinaryTreeNode<ExpressionTreeOp>>(); UnorderedListADT<Integer> levelList = new ArrayUnorderedList<Integer>(); BinaryTreeNode<ExpressionTreeOp> current; String result = ""; int printDepth = this.getHeight(); int possibleNodes = (int) Math.pow(2, printDepth + 1); int countNodes = 0; nodes.addToRear(root); Integer currentLevel = 0; Integer previousLevel = -1; levelList.addToRear(currentLevel); while (countNodes < possibleNodes) { 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 + " "; } } if (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 + " "; } } return result; }
Math.pow(2, printDepth + 1)
按照老师讲的应该是2^printDepth - 1
,可是算法给出的是2^(printDepth+1)
,实际上咱们调用的getHeight()方法会从第零行开始计算,而在其实是从一层开始的,这样的话就须要把再加1。而尾部的减1,没有再此体现。在后面的while循环的条件来看,记录输出结点数量的变量 < possibleNodes,这样的话就可使得记录输出结点数量的变量最大状况等于possibleNodes - 1,这样就是最大结点数。还有三个整形变量,一个是countNodes,是记录输出的结点数目的;一个是currentLevel记录当前结点所在的层;一个是previousLevel记录的是当前结点的前一层。过程:调出根结点A,此时对应的层数是-1,存放到对应的无序列表中。此时,countNodes(输出的结点数目)的初始值为0,
开始第一次进入循环,countNodes加1,调出无序列表中的结点。此时根结点的层数为0,前一层为-1,进入第一个条件,换行previousLevel等于currentLevel(两个变量值都为0),而后输出根节点的内容,跳出第一个条件。进入第二个条件,将根结点的左子结点添加到无序列表的尾部,对应的记录层数的无序列表添加数字1,再将根结点的右子结点添加到无序列表,对应记录层数的无序列表添加数字1,第一次循环结束。
进行第二次循环,此时调出根结点的左子结点的内容和左子结点的层数,层数为1,前一层是0,进入第一个条件,换行previousLevel等于currentLevel(两个变量值都为1),而后输出左子结点的内容,跳出第一个条件。进入第二个条件,往里面插入左结点的子结点,此时存放节点的无序列表内有和输出的左结点同一层的右结点,和左结点的两个子结点,先左节点后右结点,对应的层数应该均为3,第二次循环结束。
进行第三次循环,此时调出的是根结点的右子结点和层数,层数和左结点相同也为1,进入第一个条件(else部分),取消了换行和previousLevel等于currentLevel,这样的话就和左子结点同行输出,把根结点的两个子结点都输出来了。跳出第一个条件,再将右结点的两个子结点和对应的层数放到无序列表,其中两个子结点的层数均为2,第三次循环结束。
进行第四次循环,此时调出的根结点的左结点的左子结点,此时对应的层数是2。此时的previousLevel为1,currentLevel为2,进入第一个条件的if部分,进行换行并输出该结点的内容,跳出第一个条件,由于该结点为空,因此进入第二个条件的else部分,会默认添加该结点的两个子结点,可是子结点的内容为空,即插入到无序列表的内容为空,可是层数会进行增长,第四次循环结束。
重复进行上述循环(已经调用整个部分的相关代码,股不在叙述操做),最后达到循环超过该树的总结点数即possibleNodes跳出循环,输出result就是整个树了。express
问题3的解决方案:针对这个问题,刚开始只是敲上去而没有真正去运行。后来听同窗的运行以后有问题,这才去运行,结果然有问题。不能转化为String,很神奇!!!明明在txt文件内已经有了内容的,就是转换不成String。刚开始觉得是读文件的部分有问题,可是没找到问题,经过单步调试也只是在最后一步有问题。因此,很疑惑!更关键的是这个一样的代码在别的电脑上会有运行成功的。相同的一段代码,个人电脑上会提醒有个判断老是false,而别的上面就没有。很迷...经过侯泽洋的帮助,是咱们在得到左结点或是右结点时候只是调出其中的内容,该节点的子结点根本没有调出来致使的,彻底就是个只有该结点的一个树了,在LinkedBinaryTree中添加几句就能够结点的子结点都调出来了。数组
- 始终有问题的部分:
![]()
- 错误图片:
- 王文彬提供的代码(修改位置):
![]()
- 侯泽洋提供的代码(修改位置):
问题1的解决方案:return super.toString();
会出现带有包名的哈希码,没有正常的输出内容。准备从新书写的输出的代码的时候,发现若是输出的话就须要用递归的方法,来从树中一层一层的从左往右的按顺序输出。可是若是用到了递归的话,注定用String类型的变量输出不出来(由于要进行一个叠加的过程,而设置变量的话也不能在此方法下进行输出。须要像以前的那个归并排序和快速排序同样,一个进行递归的主要方法,另外一个调用该递归方法,来达到代码的实现。)图过期用递归来实现的话,就能够运用不一样的遍历方式。经过书上代码--表达式树的输出树状形式,就直接搬过来实现toString方法(相关代码分析在教材分析总结)。数据结构
- 产生带包名哈希码:
- 前序输出:从根结点开始,访问每个结点及其子结点。因此,先调出根结点的内容,而后从左结点开始调出至右结点的内容。
- 中序输出:从根结点开始,先访问结点的左子结点的内容,在调出该结点的内容,再访问结点的右子结点的内容。
- 后序输出:从根结点开始,先访问该结点的子结点的内容,在退回到结点的内容。
- 层序输出:从根节点开始,每一层的从左到右的进行输出。
![]()
- 树状输出(借鉴表达式树的形式):
问题2解决方案:书上表达式树的代码在进行树的输出时候,总会输出的稀乱稀乱的一堆,代码也没有爆红。第一次经过单步调试发现,是本身的getHeight()方法的方法体没有写,致使输出的结果老是0。还要本身修改getHeight()...悲惨自行补了相关代码,先判断树是否是空的,不空的话经过PP10.3作的代码,进行判断是不是叶结点进行循环遍历,在遍历的过程当中进行计数。可是在输出树的状况下就是缺最后一行,经过尝试对一个已知高度的树调用getHeight()方法时,在输出的时候发现会比实际高度少1,因此在计数变量的初始值从0改成1尝试一下,结果就完整了。学习
- 第一次修改:
- 第二次修改:
- 第三次修改:
无错题,终于不用错题总结了...this
本周结对学习状况
20172314方艺雯
20172323王禹涵
结对学习内容:树
第十章的树学起来很费劲,彻底的一个接着一个,没有顺序,没有结构的(二叉树还好点)。课后的代码相对简单,可是书上的示例代码写的比课后代码还麻烦。很是感谢侯泽洋的帮助,帮助我更好的理解树的相关知识,有些代码的问题是在帮助下完成的,这也显示出个人不足,没有更好的掌握知识,逻辑的相关内容只有本身弄懂才行,别人的帮助只是辅助的。起初还感受前面代码相对简单,但那是到了树的部分真是欲哭无泪的感受。只能再好好的学习学习再学习了。
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 0/0 | 1/1 | 15/15 | |
第二周 | 703/703 | 1/2 | 20/35 | |
第三周 | 762/1465 | 1/3 | 20/55 | |
第四周 | 2073/3538 | 1/4 | 40/95 | |
第五周 | 981/4519 | 2/6 | 40/135 | |
第六周 | 1088/5607 | 2/8 | 50/185 |