前序遍历(根在前):根结点 —> 左子树 —> 右子树
中序遍历(根在中):左子树—> 根结点 —> 右子树
后序遍历(根在后):左子树 —> 右子树 —> 根结点
在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层(h从1开始),则该层包含 1~ 2^(h-1) 个节点。
/**
* 二叉树定义
*/
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(){}
public TreeNode(int val){
}
public TreeNode(int val, TreeNode left, TreeNode right){
this.val = val;
this.left = left;
this.right = right;
}
}
递归三要素:
1. 确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。
2. 确定终止条件: 写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。
3. 确定单层递归的逻辑: 确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。
前序遍历
class Solution {
public List preorderTraversal(TreeNode root) {
// 递归三要素
List result = new ArrayList<>();
preoder(root,result);
return result;
}
// 1.入参,返回值
void preoder(TreeNode root,List result){
// 2.出栈条件
if(root == null){
return;
}
// 前序遍历,中–左–右
// 3.单层执行递归逻辑
result.add(root.val);
preoder(root.left,result);
preoder(root.right,result);
}
}
中序遍历
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
// 递归三要素,入参-返回;终止条件;单层逻辑
preorder(root,result);
return result;
}
void preorder(TreeNode root,List<Integer> result){
if(root == null){
return;
}
preorder(root.left,result);
result.add(root.val);
preorder(root.right,result);
}
}
后序遍历
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
preorder(root,result);
return result;
}
void preorder(TreeNode root,List<Integer> result){
if(root==null){
return;
}
preorder(root.left,result);
preorder(root.right,result);
result.add(root.val);
}
}