LeetCode题目中,二叉树的遍历方式是醉基本的,也是最重要的,我们将从
前序
,中序
,后续
,层序
四种遍历方式,总结他们的递归和迭代解法
递归版本
递归版本其实都比较简单,
面试时说一嘴即可,问道的时候
;其实递归版本借助了JAVA的内部栈实现,我们使用迭代版本的时候,就是显示的把栈定义出来
对于前中后序遍历,只需要将递归函数里的
res.append(root.val)
放在不同的位置,然后调用递归函数就可以
迭代版本
模板
- 初始化
栈
,存放结果的list
以及cur
- 进行迭代
while(栈不为空或者cur部位空)
- 不断进行遍历这颗树,
cur向左下进展或右下进展
- 弹出栈顶的元素,
- 不断进行遍历这颗树,
前序遍历的迭代版本
前序遍历
:根节点 ------左子树----右子树
每拿到一个 节点 就把它保存在 栈 中
继续对这个节点的 左子树 重复 过程1,直到左子树为 空
因为保存在 栈 中的节点都遍历了 左子树 但是没有遍历 右子树,所以对栈中节点 出栈 并对它的 右子树 重复 过程1直到遍历完所有节点
/**
* 套用模板实现
* @param root
* @return
*/
public List<Integer> preorderTraversal2(TreeNode root){
//保存结果
List<Integer> rs = new ArrayList<>();
//使用栈
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
if(root==null) return rs;
while (!stack.isEmpty()||cur!=null){
while (cur!=null){//根借点和左孩子入栈
stack.add(cur);
//在入栈的时候九江结果加入到结果集中
rs.add(cur.val);
//不断去看左孩子
cur=cur.left;
}
//每弹出一个元素,就到达了右孩子
TreeNode temp = stack.pop();
cur = temp.right;
}
return rs;
}
中序遍历的迭代版本
/**
* 使用模板实现中序遍历
* @param root
* @return
*/
public List<Integer> inorderTraversal2(TreeNode root){
List<Integer> rs = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
if(root==null) return rs;
while(cur!=null||!stack.isEmpty()){
//不断向左侧探索
while(cur!=null) {
stack.add(cur);
cur = cur.left;
}
//左侧探测完了
TreeNode temp = stack.pop();
rs.add(temp.val);
//将右子树加入栈中
cur = temp.right;
}
return rs;
}
后续遍历的迭代版本
/**
* 后续遍历
* 借助于谦虚遍历 中右左
* @param root
* @return
*/
public List<Integer> postorderTraversa2(TreeNode root){
Stack<TreeNode> stack = new Stack<>();
List<Integer> rs = new ArrayList<>();
TreeNode cur = root;
if(root==null) return rs;
while (!stack.isEmpty()||cur!=null){
while (cur!=null){
rs.add(cur.val);
stack.add(cur);
cur=cur.right;
}
TreeNode temp = stack.pop();
cur=temp.left;
}
//对遍历得到的结果进行反转
Collections.reverse(rs);
return rs;
}