目录
前中后序通用模板一
class Solution {
class VisitNode {
TreeNode node;
String visit;//fal代表未访问过得结点,tru代表已访问结点
public VisitNode(TreeNode node,String visit){
this.node = node;
this.visit = visit;
}
}
public List<Integer> postorderTraversal(TreeNode root) {
if(root == null) return new ArrayList<Integer>();
List<Integer> res = new ArrayList<>();
Stack<VisitNode> stack = new Stack<>();
stack.push(new VisitNode(root,"fal"));
while(!stack.empty()){
VisitNode cn = stack.pop();
if(cn.visit.equals("fal")){
//后续********************************************
stack.push(new VisitNode(cn.node,"tru"));
if(cn.node.right != null) stack.push(new VisitNode(cn.node.right,"fal"));
if(cn.node.left != null)stack.push(new VisitNode(cn.node.left,"fal"));
//前序********************************************
//if(cn.node.right != null) stack.push(new VisitNode(cn.node.right,"fal"));
//if(cn.node.left != null)stack.push(new VisitNode(cn.node.left,"fal"));
//stack.push(new VisitNode(cn.node,"tru"));
//中序********************************************
//if(cn.node.right != null) stack.push(new VisitNode(cn.node.right,"fal"));
//stack.push(new VisitNode(cn.node,"tru"));
//if(cn.node.left != null)stack.push(new VisitNode(cn.node.left,"fal"));
}else{
res.add(cn.node.val);
}
}
return res;
}
}
前中后序通用模板二
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new LinkedList<>();
Stack<TreeNode> st = new Stack<>();
if (root != null) st.push(root);
while (!st.empty()) {
TreeNode node = st.peek();
if (node != null) {
st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中
if (node.right!=null) st.push(node.right); // 添加右节点(空节点不入栈)
if (node.left!=null) st.push(node.left); // 添加左节点(空节点不入栈)
st.push(node); // 添加中节点
st.push(null); // 中节点访问过,但是还没有处理,加入空节点做为标记。
//中序
//st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中
//if (node.right!=null) st.push(node.right); // 添加右节点(空节点不入栈)
//st.push(node); // 添加中节点
//st.push(null); // 中节点访问过,但是还没有处理,加入空节点做为标记。
//if (node.left!=null) st.push(node.left); // 添加左节点(空节点不入栈)
//后序
//st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中
//st.push(node); // 添加中节点
//st.push(null); // 中节点访问过,但是还没有处理,加入空节点做为标记。
//if (node.right!=null) st.push(node.right); // 添加右节点(空节点不入栈)
//if (node.left!=null) st.push(node.left); // 添加左节点(空节点不入栈)
} else { // 只有遇到空节点的时候,才将下一个节点放进结果集
st.pop(); // 将空节点弹出
node = st.peek(); // 重新取出栈中元素
st.pop();
result.add(node.val); // 加入到结果集
}
}
return result;
}
}
前序遍历
非递归实现
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
//非递归实现
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
Deque<TreeNode> stack = new LinkedList<>();
if(root == null){
return list;
}
stack.push(root);
// while(stack != null){报NoSuchElementException,这样判断
//相当于判断stack是否实例化,实例化就为true,
//前面定义已经实例化了,所以就一直执行,到最后树遍历完了,
//栈内没有元素了,仍能进去循环。
while(!stack.isEmpty()){
TreeNode node = stack.pop();
list.add(node.val);//先放右,在放左,pop的时候才能先左
if(node.right != null){
stack.push(node.right);
}
if(node.left != null){
stack.push(node.left);
}
}
return list;
}
}
递归实现
//必须定义一个函数,不然直接在preorderTraversal函数上,
//list没法处理,每次递归都创建新的list。
//递归实现
public void pre(TreeNode root, List<Integer> list){
if(root == null){
return;
}
list.add(root.val);
pre(root.left,list);
pre(root.right,list);
}
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
pre(root,list);
return list;
}
中序遍历
非递归实现
//非递归
//非递归就是递归的变形,递归隐式的维护了一个栈,迭代就是要把这个栈表示出来。
//同样思路,都是先往左走,直到为空,然后弹出,再往右走。
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
Deque<TreeNode> stack = new LinkedList<>();
if(root == null){
return list;
}
while(!stack.isEmpty() || root != null){
while(root != null){
stack.push(root);
root = root.left;
}
root = stack.pop();
list.add(root.val);
root = root.right;
}
return list;
}
递归实现
//递归
public void inner(TreeNode root, List<Integer> list){
if(root == null) return;
inner(root.left,list);
list.add(root.val);
inner(root.right,list);
}
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
inner(root,list);
return list;
}
爱的
后序遍历
非递归实现一
这种方法与前序遍历的方法类似,知识交换了入栈顺序,然后最后将得到的结果在进行翻转。
// 后序遍历顺序 左-右-中 入栈顺序:中-左-右 出栈顺序:中-右-左, 最后翻转结果
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
if (root == null){
return result;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()){
TreeNode node = stack.pop();
result.add(node.val);
if (node.left != null){
stack.push(node.left);
}
if (node.right != null){
stack.push(node.right);
}
}
Collections.reverse(result);
return result;
}
}
非递归实现二
//非递归
public List<Integer> postorderTraversal(TreeNode root) {
// 初始化结果集
List<Integer> res = new ArrayList<>();
if (root == null) {
return res;
}
// 创建栈
Deque<TreeNode> stack = new LinkedList<>();
// 标识:上一次处理的节点
TreeNode prev = null;
// 如果当前处理节点不为空或者栈中有数据则继续处理
while (root != null || !stack.isEmpty()) {
while (root != null) {
// 如果当前处理节点不为空则入栈
stack.push(root);
// 寻找左子树
root = root.left;
}
// 拿取栈顶节点
root = stack.pop();
// if逻辑
// root.right == null 表示当前节点为根节点
// root.right == prev 如果右子树是上一次处理的节点则处理根节点
// else逻辑
// 右子树不为空,左子树找到根,根找到右子树,先处理右子树
if (root.right == null || root.right == prev) {
res.add(root.val);
// 打标
prev = root;
root = null;
} else {
// 重新把根节点入栈,处理完右子树还要回来处理根节点
stack.push(root);
// 当前节点为右子树
root = root.right;
}
}
return res;
}
递归实现
//递归
public void inner(TreeNode root, List<Integer> list){
if(root == null) return;
inner(root.left,list);
list.add(root.val);
inner(root.right,list);
}
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
inner(root,list);
return list;
}