class Solution {
//声明列表
ArrayList list = new ArrayList<>();
public List postorderTraversal(TreeNode root) {
// 如果根节点为空,则直接返回空列表
if (root == null){
return new ArrayList<>();
}
//判断此节点的左节点是否为空,如果不为空则将递归遍历此节点的左子树
if (root.left != null){
postorderTraversal(root.left);
}
//判断此节点的右节点是否为空,如果不为空则将递归遍历此节点的右子树
if (root.right != null){
postorderTraversal(root.right);
}
//节点不为空,将节点的值添加进列表中
list.add(root.val);
//最后返回列表
return list;
}
}
我们通过观察发现,这代码怎么这么像,是的就是很像,他们唯一的区别就是`list.add(root.val);`代码的位置不一样,这行代码就代表文中的 **遍历(访问)**
下图中为前序遍历(**根**左右)
![](https://upload-images.jianshu.io/upload_images/24195226-86f2674a452f8fe2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
下图中为中序遍历(左**根**右)
![](https://upload-images.jianshu.io/upload_images/24195226-c2100f0b2760e563.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
下图中为后序遍历(左右**根**)
![](https://upload-images.jianshu.io/upload_images/24195226-a509256842c6f3f8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
## 二叉树非递归遍历
> * 用到栈(FILO 先进后出的特性)
> * 每段代码后,都有栈和其中元素的关系具体过程,建议静下心来慢慢看,有助于理解代码如何运行
* 前序遍历
class Solution {
List list = new ArrayList();
public List preorderTraversal(TreeNode root) {
//如果根节点为空,则直接返回空列表
if(root==null){
return new ArrayList();
}
//声明一个栈
Stack stack = new Stack<>();
//将节点入栈
stack.push(root);
//如果栈不为空
while (!stack.empty()){
//从栈弹出这个节点
TreeNode node = stack.pop();
//添加进列表中
list.add(node.val);
// 如果这个节点的右子节点不为空
if (node.right!=null){
// 将其入栈 因为栈是先进后出,所以先压栈右子节点 后出
stack.push(node.right);
}
// 如果这个节点的左子节点不为空
if (node.left!=null){
// 将其