对于二叉树而言,主要有三种遍历方式:前序遍历、中序遍历和后序遍历 (当然,还有层序遍历,但不在本的讨论范围内)。前中后是对于根节点而言的,前序就是“先根再左最后右”,而中序就是“先左再根最后右”,后序自然就是“先左再右最后根”。
实现二叉树的遍历,主要有递归和迭代两种方法,递归方法相对较为简单,这里就不做说明了,直接上代码
递归
// 前序
class Solution {
public List<Integer> res=new ArrayList<>();
public List<Integer> preorderTraversal(TreeNode root) {
method(root);
return res;
}
void method(TreeNode root){
if(root==null) return;
res.add(root.val);
method(root.left);
method(root.right);
}
}
// 中序
class Solution {
List<Integer>list=new ArrayList();
public List<Integer> inorderTraversal(TreeNode root) {
helper(root);
return list;
}
void helper(TreeNode root){
if(root==null) return ;
helper(root.left);
list.add(root.val);
helper(root.right);
}
}
// 后序
class Solution {
List<Integer>res=new ArrayList();
public List<Integer> postorderTraversal(TreeNode root) {
helper(root);
return res;
}
void helper(TreeNode root){
if(root==null) return;
helper(root.left);
helper(root.right);
res.add(root.val);
}
}
迭代
迭代相对于递归难了一点点,但其实也比较好理解,前中后序遍历都是借助栈“先进后出,后进先出”这个特性来完成的
前序
前序遍历是“根->左->右",我们从根节点开始不断往其左子节点遍历,将遍历到的值加入结果集中。同时借助一个栈来将遍历过的节点压入栈中,这样在遍历到左节点为null时,就可以弹出栈中的一个节点,从这个节点的右节点开始遍历
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer>res=new ArrayList();
Deque<TreeNode>stack=new LinkedList();
TreeNode node=root;
while(node!=null||!stack.isEmpty()){
if(node!=null){
res.add(node.val);
stack.push(node);
node=node.left;
}else{
node=stack.pop();
node=node.right;
}
}
return res;
}
中序
中序遍历的思路跟前序遍历的差不多,主要的不同点在于,中序遍历的顺序为"左->根->右",所以不能像前序遍历那样在遍历到节点时就将节点的值加入结果集,而是在将节点从栈中弹出时再将节点值加入结果集
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer>res=new ArrayList();
Deque<TreeNode>stack=new LinkedList();
TreeNode node=root;
while(node!=null||!stack.isEmpty()){
if(node!=null){
stack.push(node);
node=node.left;
}else{
node=stack.pop();
res.add(node.val);
node=node.right;
}
}
return res;
}
后序
后序遍历的思路就跟上面两种稍有不同了,因为后序的遍历顺序是"左->右->根",按照前面两种方法是无法实现这个遍历顺序的,那么我们可以转变思路,将“左->右->根"变为"根->右->左" ,之后将遍历到的值采用头插入法插入结果集即可,其它的实现都跟前序遍历一致
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer>res=new ArrayList();
TreeNode node=root;
Deque<TreeNode>stack=new LinkedList();
while(node!=null||!stack.isEmpty()){
if(node!=null){
res.add(0,node.val);
stack.push(node);
node=node.right;
}else{
node=stack.pop();
node=node.left;
}
}
return res;
}