第五章小结与习题小结

第五章应该是一条分割线了,前面四章讲的都是线性结构,接下来的就是非线性结构了。无疑问的是非线性结构是要比线性结构要难的了,毕竟从一对一到一对多还是有一定的差距的。哈哈,其他的也不多说了,我们开始这一章的小结吧。

 

正如第五章的题目“树和二叉树”一般,我也觉得这一章的学习就是分为两个部分,一个是树,一个则是二叉树。

对于普通的树,我觉得我们主要是要掌握它的一些基本的术语,这会使得后面的操作更加的清晰明了。我小结了一下,大概可以如下图一般,概念可能比较难记,结合图来记会使记忆更加牢固。

接下来,我们就来看看这一章的大头了。二叉树顾名思义,就是一个节点至多只有两颗子树的树,左边的为左子树,右边则为右子树。二叉树作为特殊的树,普通的树的概念自然适用于二叉树。当然,二叉树也有特别的一些概念。觉得以下这两个概念比较容易混淆,在这里做个区别。

 满二叉树:

深度为k且含有2^k -1个结点的二叉树,通俗来讲就是每一个层次都填满的二叉树。

 完全二叉树:

  1. 叶子结点只可能在层次最大的两层上出现。
  2. 最后一层之前为满二叉树,最后一层靠左对齐。

 还是和之前学习线性结构一样,接下来要考虑的就是具体的存储结构和操作了。存储结构也还是分为了顺序存储和链式存储,但其中还可以分出四种不同的标识方法:双亲表示法,孩子表示法,双亲孩子表示法以及孩子兄弟表示法。

 对于二叉树的特殊结构也引出了四种特殊的遍历的方法:先序遍历,中序遍历,后序遍历以及层次遍历。前面三种遍历有着同工异曲之妙,在这里就只介绍中序遍历。

 中序遍历的具体操作定义:

若二叉树为空,则进行空操作,否则:

  1. 中序遍历左子树
  2. 访问根节点
  3. 中序遍历右子树

 从定义来看,很明显这是一个递归的操作,根据定义则可以得到代码如下:

1 public void inOrderTraverse1(TreeNode root) {  
2         if (root != null) {  
3             inOrderTraverse1(root.left);  
4            cout<<root.data;5             inOrderTraverse1(root.right);  
6         }  
7     } 

 

 在做题的时候就碰到了要求层次遍历的题目,及由左到右,由上到下对树进行一个遍历。不瞒你说,我确实没想到什么好的方法,但是百度了一下我就恍然大悟了,使用队列先进先出的性质正好就和要求相呼应。以下是我在CSDN上找到的一篇博客,我觉得很有意义,这里分享一下:

https://blog.csdn.net/hansionz/article/details/81947834

我觉得这一次的作业和实践的题目都比较有意思,所以在这里也来谈论一下。

首先是第一题:输出树节点。

 

这道题给我最大的困扰就是输入了。平常我们所遇到的输入都是比较简单的纯粹的输入,而这一次一开始我看了很久都没有看出来,输入究竟是什么意思。

 

一开始的时候以为这一个一个节点就是顺着排的,就像第二行输入,节点左子树的编号为1,而右子树为空。这样一理解后,我就画不出来图了。后来又反复读了很多次的题目,才明白1是指第一个节点。

 

(失败的探索过程

明白了题目的意思之后,输入的问题也就得到了解决。发现了这道题目与下标密切关系,于是我便选择了数组的存储形式。

 

接下来就是一些细节问题,因为输入的时候,在为空的时候题目给了符号-’来表示,因此我们需要在输入的时候以字符的形式进行输入,而后根据其ASCII码再转化为整型。

在这里,还很容易出现一个问题,就是我们往往只关注了输入的内容,却忘记了题目自身的条件。如上图我所定义的结构类型,其中有一个data,实际上就是代表第几个节点,即下标。

但我们在初始化的时候往往会忘记给data初始化,最后就导致该值为随机值,答案也得不到正确的。

 

 

接下来就是层次遍历输出树节点了,这里上面的时候已经进行了说明,但这里还是要强调的是,正如老师上课讲的,我们要明确在队列里面排列的是什么,是地址,还是下标,又或者是其他的。一开始我就是没有明白究竟在队列里面排列的是什么,导致了后面的思路一团乱

 

其实深入虎穴和前面的这道题是差不多一样的道理,只是从二叉树变成了普通的树,实际上存储的方式并没有太大的改变。但由于题目的数据比较大,而且不确定这个时候采用动态的数组使得题目更加容易得到解决。一开始我采用了二维数组的形式,理解确实好理解,但运行的时候就内存爆了。

 

最后要讲的就是同构树这一题了。看到这道题题目的时候,我就想着能不能投机取巧,直接进行判断对比,连树都不构建,后来发现题目并不是那么简单,是经过若干次的左右子树对调若能两棵树可以吻合就为同构。

 

于是我便开始踏踏实实一步一步来了。首先将两棵树构建起来。对于这道题一开始我真的没想到用递归的办法,我就一直在想怎么样一层一层的对比,毕竟只是左右子树的对调,于是我就利用了之前学的层次遍历的方法,一层一层的比较。

具体的思路就是在入队前进行一个判断,看两棵树左右子树根是否相同或者相反,相同则正常进行入队,如果相反则将第二颗树先右后左进行入队

 

虽然有点笨,但是做出来感觉还是不错的。后来去网上借鉴的时候,看到了递归的方法,也觉得确实比我的方法更加的机智。

后来过pta的时候,也还是出现了问题,缺少了空树的情况。

 

虽然只是一个句子可以搞定的问题,但却有时会是一个巨大的漏洞。

上一次的目标基本完成了,较好的掌握了KMP算法,因为这一次的实践题老师带我们领略了一下STL的魅力,我下一次的目标就想多去了解一些关于STL方面的知识。

posted @ 2019-05-03 19:50  zerozerozerozero  阅读(187)  评论(2编辑  收藏  举报