二叉树
二叉树的前序、中序、后序遍历(深度优先遍历)
递归遍历
常规题。明确:
1、确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。
2、确定终止条件: 写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。
3、确定单层递归的逻辑:确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。
迭代遍历——非递归遍历、利用栈
前序、后序类似。中序需要特别注意。
前序:结点先入栈。再执行循环判断,遍历右子树左子树。
中序:先new一个新结点来存放当前节点。再执行循环判断,循环判断中将结点入栈出栈以及遍历左右节点。需要注意一下循环条件:while( cur != null || !stack.isEmpty() )
后序: 后序遍历只需改动一下前序遍历,左子树和右子树入栈的顺序,最后翻转一下数组即可。
可直接调用java翻转函数:
//List翻转,只能翻转List类型
Collections.reverse(result);
层序遍历(广度优先遍历)
递归:没记
迭代——利用队列
先入队根节点。当队列不为空时循环,出队一个队头结点,入队它的左右结点。
待刷:
102.二叉树的层序遍历- 107.二叉树的层次遍历II
- 199.二叉树的右视图
- 637.二叉树的层平均值
- 429.N叉树的层序遍历
- 515.在每个树行中找最大值
- 116.填充每个节点的下一个右侧节点指针
- 117.填充每个节点的下一个右侧节点指针II
104.二叉树的最大深度111.二叉树的最小深度
226.翻转二叉树
递归:前序或者后序
迭代:层序遍历
只需要一个队列即可,与层次遍历二叉树类似。
101.对称二叉树 2
递归
明确三步走:参数和返回值,终止条件,单词递归逻辑
只能后序,先递归外侧左右对称结点(左左、右右),再递归内侧对称结点(左右、右左);判断二者返回值是否一致。
tips:判断两个boolean类型的数值是否一致,用&&。
Boolean result = compareOutside && compareInside;
迭代:(非层序遍历)
使用队列/使用栈
无论时使用栈还是队列,只是找一个数据结构来存放当前比较的两个结点。
先将两个结点存入栈/队列中。再循环判断。弹出这两个结点,判断是否对称,一共有5种可能的情况,当这两个节点对称时,弹入外侧左右对称结点(左左、右右),内侧对称结点(左右、右左)继续判断。
104.二叉树的最大深度
递归(后序)
常规——明确三步走
迭代(层序)
待刷
559.n叉树的最大深度
递归(后序)
明确三步走
单次递归的逻辑中与二叉树的区别:
1、二叉树只有两个孩子,可以直接max.(left, right)。
2、但是n叉树有多个孩子,需要声明一个depth变量,记录for循环中当前的结点全部孩子的最大深度。
迭代(层序)
待刷
111.二叉树的最小深度
递归(后序)
明确三步走
单次递归逻辑中,最小深度是分三种情况:
1、左子树为空,最小深度为右子树+1
2、右子树为空,最小深度为左子树+1
3、其他情况(左右子树都不为空),最小深度才为 min(left, right) + 1。
迭代(层序)
待刷
222.完全二叉树的节点个数
普通二叉树的节点个数实现:
递归
常规——明确三步走
迭代(层序)
待刷
利用完全二叉树特性的节点个数实现
没记