树与二叉树堆:经典OJ题集(1)

目录

查找值为x的结点:

思路分析:

单值二叉树: 

示例: 

 思路分析: 

相同的树:

示例: 

思路分析: 

二叉树的前序遍历:——使用前序遍历把结点元素放入数组中 

题目:

示例: 

思路分析: 

代码调用图 

通过前序遍历的数组构建二叉树 :

题目:

通过前序遍历的数组"ABD##E#H#CF##G##"构建二叉树

思路分析: 

代码调用图 

总结:


查找值为x的结点:

使用前序、中序后序中的一种对二叉树进行遍历,查找出值为x的结点 

思路分析:

在前中后序中,前序和中序、后序相比在调用递归的次数和返回重复结点的次数较少,所以采取前序遍历进行遍历查找。

查找值为x的结点,可以转变为查找结点以及结点的左右孩子结点的元素是否等于x,而左右孩子结点也有它们的左右孩子,于是最后就将问题化解成了查看当前结点的值是否等于x

  • 而若找到了值等于x的结点,则返回上一个结点,并使用上一个结点的指针指向,且需要使用临时变量接收。
  • 且根据前序遍历的方法,可以将当结点等于NULL作为结束条件,表示当前左右子树走完,当前子树并没有等于x的结点。

单值二叉树: 

题源:965. 单值二叉树 - 力扣(LeetCode) 

  • 如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。只有给定的树是单值二叉树时,才返回 true;否则返回 false

示例: 

 思路分析: 

  • 根据二叉树的结构划分和等值传递原理,本问题可以化解为根结点是否和左右孩子结点有相等的元素,而左右孩子也具有它们自己的左右孩子结点
  • 所以到最后本问题就变成了查看根结点是否等于左孩子结点的元素,是否等于右孩子结点的元素。
  • 也就是说,当根结点元素和左右孩子中的一个孩子结点元素不相同就返回fasle,但是如果相同就需要进入左右孩子结点,去判断它们是否与它们的左右孩子结点元素是否相同。

需要注意的是,有一些结点是只有左孩子结点的,没有右孩子结点,遇到这种情况,也就是当root==NULL时,返回的是true

相同的树:

题源:100. 相同的树 - 力扣(LeetCode) 

  • 给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。
  • 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

示例: 

思路分析: 

需要判断两颗树是否在结构上和元素上相同,那么就需要同时遍历两棵树

而将本问题化解为最简易的问题那便是查看两个根结点是否同时存在,在两个根结点同时存在的时候:

同时判断两个根结点的左右孩子结点又是否同时存在:

  • 如果一方的左孩子结点或者右孩子结点不存在,而另一方的左孩子结点或者右孩子结点存在,那结构就不一样了,所以返回false

若两个根结点的左右孩子结点同时存在,则就同时判断两个根结点的左孩子结点的值是否相同,判断两个根结点的右孩子结点的值是否相同:

  • 如果不相同就返回false
  • 如果相同则进入各自的左右孩子结点进行判断它们的左右孩子结点是否一样。

二叉树的前序遍历:——使用前序遍历把结点元素放入数组中 

题源:144. 二叉树的前序遍历 - 力扣(LeetCode) 

题目:

  • 给你二叉树的根节点 root ,返回它节点值的 前序 遍历

示例: 

思路分析: 

因为需要把结点元素存储到数组中,所以我们需要创建数组,同时数组的大小要等于结点的个数,防止空间浪费和空间不足,因此在外另设一个函数进行递归调用计算树的结点个数以此来创建数组 

  • returnsize 是表是数组的大小 ,a是数组名

  • 再创建一个函数用来递归使用 

因为采取了前序遍历进行存储,所以利用了前序遍历,且直接将原先前序遍历的打印变成了将元素存储到数组内 

原前序遍历:树与二叉树堆:链式二叉树的实现-CSDN博客

代码调用图 

通过前序遍历的数组构建二叉树 :

题目:

通过前序遍历的数组"ABD##E#H#CF##G##"构建二叉树

思路分析: 

1、因为我们要构建二叉树,所以使用创造二叉树的函数 malloc ,因为要把数组的元素交给二叉树的结点,所以需要进行数值的传递。

2、而其次,因为使用的是前序遍历,所以是在前序遍历的方法上进行改造。

3、同时如上图所示,我们构建的二叉树是用 # 来表示最叶子结点的,于是我们可以采用结点是否是 # 来表示递归的返回条件

4、但因为是数组,所以即便是 # 也可能是在数组的中间,所以数组的下标或者说指向数组元素的指针也应该要进行前进。 

  •  a是数组名,pi是指向数组元素的指针可以看作是下标

代码调用图 


总结:

对于二叉树的递归调用而言,本质上分为了三个部分,第一个是判断二叉树逐级返回的条件,一般摆在前端,第二个是要在递归调用中指向的代码程序,第三是递归调用

而二叉树的递归调用一般是以划分成根、左右子树、左右孩子结点之间的关系,来进行大事化小的管理分化。 


 

猜你喜欢

转载自blog.csdn.net/2301_76445610/article/details/134720691