本题思路:有两种写法,一种是递归写法,一种是迭代的写法。我们一一来讲解这两种写法。
二叉树的前序遍历的顺序是: 根 左 右
我们将一根树看成 左 根 右 三个部分!,我们利用一个整体的思维,将一颗树,看成一个根,左树、右树。如下图所示。
此时我们要遍历的话,先整体遍历根,然后遍历左树,再遍历右树。 此时得到的顺序就是 根左右。
public class preorder {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new LinkedList();
preoder(root, list);
return list;
}
// 前序遍历
public void preoder(TreeNode root, List<Integer> list) {
if (root == null) {
return;
}
list.add(root.val); // 先遍历根
preoder(root.left, list); // 遍历左树
preoder(root.right, list); // 遍历右树
}
}
迭代遍历的话,我们需要借助栈来实现。利用栈的特性来完成这个前序遍历。
我们来演示下思路,利用图片的形式。
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
Stack<TreeNode> stack = new Stack();
List<Integer> list = new LinkedList<>();
if(root == null){
return list;
}
// 先将根节点进栈
stack.push(root);
while(!stack.isEmpty()){
TreeNode cur = stack.pop();
list.add(cur.val);
// 如果右孩子不为空,则就入栈
if(cur.right != null){
stack.push(cur.right);
}
// 如果左孩子不为空,则入栈
if(cur.left != null){
stack.push(cur.left);
}
}
return list;
}
}
本题思路:一种是递归版本,一种是迭代版本。下面一个一个讲解下思路。
二叉树的后序遍历的顺序是: 左 右 根
我们将一根树看成 左 根 右 三个部分!,我们利用一个整体的思维,将一颗树,看成一个根,左树、右树。如下图所示。
此时我们要遍历的话,先整体遍历左树,然后遍历右树,再遍历根。 此时得到的顺序就是 左右根。
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> list = new LinkedList();
postorder(root,list);
return list;
}
public void postorder(TreeNode root, List<Integer> list){
if(root == null){
return;
}
postorder(root.left,list);
postorder(root.right,list);
list.add(root.val);
}
}
上一题,我们进栈的顺序是,根 右 左,所以得到最终前序遍历顺序是 根左右,如果我们换一换,将入栈顺序改成 根 左 右, 此时得到的顺序就是 根 右 左。 我们再逆置一下,就是 左 右 根,这不就是我们想要的结果了吗。
所以只需要对上述代码修改三行即可
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
Stack<TreeNode> stack = new Stack();
List<Integer> list = new LinkedList<>();
if(root == null){
return list;
}
// 先将根节点进栈
stack.push(root);
while(!stack.isEmpty()){
TreeNode cur = stack.pop();
list.add(cur.val);
// 如果左孩子不为空,则入栈
if(cur.left != null){
stack.push(cur.left);
}
// 如果右孩子不为空,则就入栈
if(cur.right != null){
stack.push(cur.right);
}
}
// 逆置顺序
Collections.reverse(list);
return list;
}
}
本题思路:一种是递归版本,一种是迭代版本。下面一个一个讲解下思路。
二叉树的中序遍历的顺序是: 左 根 右
我们将一根树看成 左 根 右 三个部分!,我们利用一个整体的思维,将一颗树,看成一个根,左树、右树。如下图所示。
此时我们要遍历的话,先整体遍历左树,然后遍历根,再遍历右树。 此时得到的顺序就是 左根右。
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list = new LinkedList();
inorder(root,list);
return list;
}
public void inorder(TreeNode root, List<Integer> list){
if(root == null){
return;
}
inorder(root.left,list);
list.add(root.val);
inorder(root.right,list);
}
}
迭代写法的话,我们仍旧是利用栈,但是不能和前面两种一样,简单的调换下代码顺序就能实现了。
同样我们用一个图,来分析一下具体的一个思路。
总结来说:
- cur不为空 一直往左 cur=cur.left ,遇到左元素就入栈,
- cur 为空,就弹出栈顶元素用cur接收,并记录下来,然后 cur = cur.right
class Solution {
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 中
list.add(cur.val);
// 此时开始往右
cur = cur.right;
}
}
return list;
}
}