【Leetcode】二叉树的四种遍历方式

前序遍历

题目

给定一个二叉树,返回它的 前序 遍历。

示例:

输入: [1,null,2,3]
1

2
/
3

输出: [1,2,3]

题目链接

思路

迭代

从根节点开始,每次迭代弹出当前栈顶元素,并将其孩子节点压入栈中,先压右孩子再压左孩子。

代码

package com.alone.test.leetcode;

import javax.naming.LinkLoopException;
import java.util.LinkedList;
import java.util.List;

/**
 * @BelongsProject: JavaSourceNotes
 * @BelongsPackage: com.alone.test.leetcode
 * @Author: Alone
 * @CreateTime: 2020-08-20 07:37
 * @Description: 二叉树的前序遍历
 */
public class T144 {

    private List<Integer> result = new LinkedList<>();

    public List<Integer> preorderTraversal(TreeNode root) {
        preOrderStack(root);
        return result;
    }

    /**
     * 递归
     * @param root
     */
    private void preOrder(TreeNode root) {
        if(root == null)
            return;
        result.add(root.val);
        preOrder(root.left);
        preOrder(root.right);
    }

    /**
     * 栈迭代
     * @param root
     */
    private void preOrderStack(TreeNode root) {
        LinkedList<TreeNode> stack = new LinkedList<>();
        if(root != null)
            stack.add(root);
        while (!stack.isEmpty()) {
            TreeNode now = stack.pollLast();//获取的同时删除
            result.add(now.val);
            //要反过来,因为先遍历左子树
            if(now.right != null)
                stack.add(now.right);
            if(now.left != null)
                stack.add(now.left);
        }
    }

    /**
     * 莫里斯算法 时间复杂度O(n) 空间复杂度O(1)
     * 有点不太理解
     * @param root
     */
    private void preOrderMorris(TreeNode root) {
        TreeNode node = root;
        while (node != null) {
            if (node.left == null) {//左子树为空
                result.add(node.val);
                node = node.right;
            }
            else {
                TreeNode predecessor = node.left;
                while ((predecessor.right != null) && (predecessor.right != node)) {//找到右子树的叶节点
                    predecessor = predecessor.right;
                }

                if (predecessor.right == null) {//把当前节点与根节点连接
                    result.add(node.val);
                    predecessor.right = node;
                    node = node.left;
                }
                else{//删除虚拟路径
                    predecessor.right = null;
                    node = node.right;
                }
            }
        }
    }
}

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

中序遍历

思路

迭代

思路:每到一个节点 A,因为根的访问在中间,将 A 入栈。然后遍历左子树,接着访问 A,最后遍历右子树。

在访问完 A 后,A 就可以出栈了。因为 A 和其左子树都已经访问完成。

代码

package com.alone.test.leetcode;

import java.util.LinkedList;
import java.util.List;

/**
 * @BelongsProject: JavaSourceNotes
 * @BelongsPackage: com.alone.test.leetcode
 * @Author: Alone
 * @CreateTime: 2020-08-20 09:55
 * @Description: 二叉树的中序遍历
 */
public class T94 {

    private List<Integer> result = new LinkedList<>();

    public List<Integer> inorderTraversal(TreeNode root) {
        inOrderStack(root);
        return result;
    }

    /**
     * 递归
     * @param root
     */
    private void inOrder(TreeNode root) {
        if(root == null)
            return;
        inOrder(root.left);
        result.add(root.val);
        inOrder(root.right);
    }

    /**
     * 迭代
     * @param root
     */
    private void inOrderStack(TreeNode root) {
        LinkedList<TreeNode> stack = new LinkedList<>();
        if(root != null){
            stack.add(root);
        }
        TreeNode tmp = root;
        while (tmp != null && !stack.isEmpty()) {
            while(tmp != null){
                stack.add(tmp);
                tmp = tmp.left;
            }
            tmp = stack.pollLast();
            result.add(tmp.val);
            tmp = tmp.right;
        }
    }
}

后序遍历

代码

package com.alone.test.leetcode;

import java.util.LinkedList;
import java.util.List;

/**
 * @BelongsProject: JavaSourceNotes
 * @BelongsPackage: com.alone.test.leetcode
 * @Author: Alone
 * @CreateTime: 2020-08-22 09:35
 * @Description:
 */
public class T145 {
    
    private LinkedList<Integer> result = new LinkedList<>();

    public List<Integer> postorderTraversal(TreeNode root) {
        postOrderStack(root);
        return result;
    }

    private void postOrder(TreeNode root) {
        if(root == null)
            return;
        postOrder(root.left);
        postOrder(root.right);
        result.add(root.val);
    }

    private void postOrderStack(TreeNode root) {
        LinkedList<TreeNode> stack = new LinkedList<>();
        if(root != null)
            stack.add(root);
        while (!stack.isEmpty()) {
            TreeNode tmp = stack.pollLast();
            result.addFirst(tmp.val);
            if(tmp.left != null)
                stack.add(tmp.left);
            if(tmp.right != null)
                stack.add(tmp.right);
        }
    }
}

层序遍历

题目

给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。

示例:
二叉树:[3,9,20,null,null,15,7],

3

/
9 20
/
15 7
返回其层次遍历结果:

[
[3],
[9,20],
[15,7]
]

题目链接

思路

采用bfs,先统计每一层的节点数,再对每一层节点进行遍历。

代码

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> result = new ArrayList<>();
        Queue<TreeNode> queue = new ArrayDeque<>();
        if (root == null)
            return result;
        else {
            queue.add(root);
            while (!queue.isEmpty()) {
                int s = queue.size();
                List<Integer> tmp = new ArrayList<>();
                while (s > 0) {
                    TreeNode node = queue.poll();
                    tmp.add(node.val);
                    if(node.left != null)
                        queue.add(node.left);
                    if(node.right != null)
                        queue.add(node.right);
                    s --;
                }
                if(tmp != null)
                    result.add(tmp);
            }
        }
        return result;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41279172/article/details/108547109