二叉树的遍历

有两种通用的遍历树的策略:

  • 深度优先搜索(DFS)
    在这个策略中,我们采用深度作为优先级,以便从根开始一直到达某个确定的叶子,然后再返回根到达另外一个分支。深度优先又细分为
    • 后序遍历: 访问根节点的操作在左右孩子之后
    • 前序遍历: 访问根节点的操作在左右孩子之前
    • 中序遍历: 访问根节点的操作在左右孩子之中
  • 广度优先搜索(BFS)
    按照高度顺序一层层的访问整棵树,高层次的结点将会比低层次的结点先被访问到。
    下面是一张示意图,树上的结点按照访问顺序来编号。

后序遍历

/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
// 反过来的前序遍历
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
LinkedList<Integer> output = new LinkedList<Integer>();
if(root == null){
return output;
}

stack.add(root);
while(!stack.isEmpty()){
TreeNode node = stack.pollLast();
output.addFirst(node.val);
if(node.left != null){
stack.add(node.left);
}
if(node.right != null){
stack.add(node.right);
}
}
return output;
}
}
// 记录结点是否被访问过的后序遍历
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
Deque<TreeNode> stack = new LinkedList<>();
Deque<Integer> flag = new LinkedList<>();
TreeNode p = root;
List<Integer> res = new ArrayList<>();
while (p != null || !stack.isEmpty()) {
while (p != null) {
flag.push(0);
stack.push(p);
p = p.left;
}
while (!stack.isEmpty() && flag.peek() == 1) {
flag.pop();
res.add(stack.pop().val);
}
if (!stack.isEmpty()) {
flag.pop();
flag.push(1);
p = stack.peek().right;
}
}
return res;
}
}

前序遍历

/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
LinkedList<Integer> output = new LinkedList<Integer>();
if(root == null){
return output;
}

stack.add(root);
while(!stack.isEmpty()){
TreeNode node = stack.pollLast();
output.add(node.val);
if(node.right!=null){
stack.add(node.right);
}
if(node.left!=null){
stack.add(node.left);
}
}
return output;
}
}

中序遍历

  • 中序遍历递归解法

    class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
    List<Integer> res = new ArrayList<>();
    if(root == null){
    return res;
    }
    helper(root, res);
    return res;
    }

    public void helper(TreeNode root, List<Integer> res){
    if(root.left != null){
    helper(root.left, res);
    }
    res.add(root.val);
    if(root.right != null){
    helper(root.right, res);
    }
    }
    }
  • 基于栈的遍历

    class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
    LinkedList<TreeNode> stack = new LinkedList<>();
    List<Integer> res = new ArrayList<>();
    TreeNode curr = root;
    while(curr != null || !stack.isEmpty()){
    while(curr != null){
    stack.push(curr);
    curr = curr.left;
    }
    curr = stack.pop();
    res.add(curr.val);
    curr = curr.right;
    }
    return res;
    }
    }

层次遍历

  • 层次遍历递归解法

    class Solution {

    List<List<Integer>> levels = new ArrayList<List<Integer>>();

    public void helper(TreeNode node, Integer level){
    if(levels.size() == level){
    levels.add(new ArrayList<Integer>());
    }

    levels.get(level).add(node.val);

    if(node.left != null){
    helper(node.left, level+1);
    }
    if(node.right != null){
    helper(node.right, level+1);
    }
    }

    public List<List<Integer>> levelOrder(TreeNode root) {
    if(root == null){
    return levels;
    }
    helper(root, 0);
    return levels;
    }
    }
  • 层次遍历迭代解法

    class Solution {

    public List<List<Integer>> levelOrder(TreeNode root) {
    List<List<Integer>> levels = new ArrayList<List<Integer>>();
    if(root == null) return levels;

    Queue<TreeNode> queue = new LinkedList<TreeNode>();
    queue.add(root);
    int level = 0;

    while( !queue.isEmpty() ){

    // 开始当前层次
    levels.add(new ArrayList<Integer>());

    // 当前层次的元素数量
    int level_length = queue.size();

    for(int i=0; i<level_length; ++i){
    TreeNode node = queue.remove();

    // 把当前层次的元素都放入返回数组中
    levels.get(level).add(node.val);

    // 添加当前层次的孩子结点到队列中为下一层次做准备
    if(node.left != null){
    queue.add(node.left);
    }
    if(node.right != null){
    queue.add(node.right);
    }
    }
    // 进行下一层次
    level++;
    }
    return levels;
    }

    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值