首先来讲一下前中后序遍历的概念
不讲那么官方,其实就我个人的理解以及看大佬的视频和帖子,“前中后”这个概念就是针对根节点的;然后牢记一句废话“左边永远在右边的左边,右边永远在左边的右边”,就可以完美玩转前中后序这种基础的二叉树遍历,举个栗子~
前序:根->左->右 -----------> 根节点在前,左在左,右在右
中序:左->根->右 ------------> 根节点在中间,左在左,右在右
后序:左->右->根 ------------->根节点在后面,左在左,右在右
下面具体到代码实现
要遍历二叉树,我们先定义一个二叉树的类
class Node{
Node left;
Node right;
int val;
Node(){
this.val=0;
}
Node(int val){
this.val=val;
}
}
以下所有代码都是基于以上的类属性来写的
先从前序遍历的递归开始,以下是我最先写的代码
前序遍历:
public class PreOrderTrevase {
//前序遍历递归
public void PreOrder(Node root){
if(root==null){
return;
}
System.out.println(root);
PreOrder(root.left);
PreOrder(root.right);
}
后来又在leetcode上看到同一道题,但是返回值是个List,也就是不输出,按照前序遍历全部都放进一个list里面
public List<Integer> PreOrderByList(Node root){
if(root==null){
return list;
}
list.add(root.val);
PreOrder(root.left);
PreOrder(root.right);
return list;
}
但是对于很多盆友来说递归太简单,于是HR也是这么想的,所以很多公司其实都不问递归问的是非递归思想及代码
在这里需要用到栈,先将根节点放入栈,然后出栈,假设他有左右节点,栈的特性是后入先出,所以应该先放右子树再放左子树,然后出左树最后出右树
List<Integer> list=new LinkedList<>();
Stack<Node> stack=new Stack<>();
Node cur=root;
while(!stack.isEmpty()||cur!=null){
if(cur!=null){ //将左子树全部压入栈
list.add(cur.val);
stack.push(cur);
cur=cur.left;
}else{
cur=stack.pop();
cur=cur.right;
}
}
return list;
中序遍历:
递归
List<Integer> list=new LinkedList<>();
public List<Integer> inOrder(Node root){
if(root==null){
return list;
}
inOrder(root.left);
list.add(root.val);
inOrder(root.right);
return list;
}
非递归
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list=new LinkedList<>();
Stack<TreeNode> stack=new Stack<>();
TreeNode cur=root;
while(cur!=null||!stack.isEmpty()){
if(cur!=null){
stack.push(cur);
cur=cur.left;
}else{
cur=stack.pop();
list.add(cur.val);
cur=cur.right;
}
}
return list;
}
后序遍历:
递归
List<Integer> list=new LinkedList<>();
public List<Integer> postOrder(Node root){
if(root==null){
return list;
}
postOrder(root.left);
postOrder(root.right);
list.add(root.val);
return list;
}
非递归
List<Integer> list = new ArrayList<>();
public List<Integer> postorderTraversal(TreeNode root) {
Stack<TreeNode> stack= new Stack<>();
TreeNode cur=root;
TreeNode pre = null;
while(cur!=null||!stack.isEmpty()){
while(cur!=null){
stack.push(cur);
cur=cur.left;
}
cur = stack.peek();
if(cur.right == null || cur.right==pre) {
list.add(cur.val);
stack.pop();
pre = cur;//代表cur已经打印
cur = null;
}else {
cur = cur.right;
}
}
return list;
}