二叉树遍历

1. 四种遍历方式

前中后序遍历相当于图论中的DFS(深度优先搜索)
层序遍历相当于图论中的BFS(广度优先搜索)

(1)前序遍历

根节点->左子树->右子树

(2)中序遍历

左子树->根节点->右子树

(3) 后序遍历

左子树->右子树->根节点

(4)层序遍历

每一层进行遍历

1.1. 力扣实现(java版)

1.1.1 (94)二叉树的中序遍历

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        inorder(root, result);
        return result;
    }

    private void inorder(TreeNode node, List<Integer> result) {
        if (node == null) return;
        inorder(node.left, result);  // 递归左子树
        result.add(node.val);              // 访问根节点
        inorder(node.right, result); // 递归右子树
    }
}

1.1.2 (144)二叉树的前序遍历

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        preorder(root,res);
        return res;
    }

    public void preorder(TreeNode root, List<Integer> res){
        if(root == null) return;
        res.add(root.val);
        preorder(root.left,res);
        preorder(root.right,res);
    }
}

1.1.3 (144)二叉树的后序遍历

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        postorder(root , res);
        return res;
    }

    public void postorder(TreeNode root,List<Integer> res){
        if(root == null) return;
        postorder(root.left,res);
        postorder(root.right,res);
        res.add(root.val);
    }
}

前面三种遍历方式使用迭代的方法,模板很固定,到根节点打印就行了。

1.1.4 (102)二叉树的层序遍历

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        //注意点1
        Queue<TreeNode> queue = new LinkedList<>();
        List<List<Integer>> res = new ArrayList<>();
        if(root != null) queue.add(root);
        while(!queue.isEmpty()){
            List<Integer> tmp = new ArrayList<>();
            //注意点2
            for(int i = queue.size();i > 0;i--){
                TreeNode node = queue.poll();
                tmp.add(node.val);
                if(node.left != null) queue.add(node.left);
                if(node.right != null) queue.add(node.right);
            }
            res.add(tmp);
        }
        return res;
    }
}

对于层序遍历,需要重点注意一下两个地方:
1. 如何存储每一层的结点数值?
对于二叉树这种数据结构,无法直接存储每一层的结点数值,只能进行DFS,因此需要换一种新的数据结构来存储-------队列,在java中通常使用LinkedList,实现了 Deque 接口(双向队列),而 Deque 继承自 Queue
而下面对输出结果res使用的是ArrayList,具有访问快,顺序好的特点。
对这两种具体实现类需要有所了解。
2.queue.size()是动态变化
在把每一层的结点数值存储到tmp中的时候,使用的for循环如下所示:

for(int i = queue.size();i > 0;i--)

而不是我们经常使用的

for(int i = 0;i < queue.size();i++)

这是因为**queue.size()**是会变化的,问题就出在循环中的

TreeNode node = queue.poll();

这行代码运行后,队列弹出一个结点,会导致queue的长度减少,这样**queue.size()**也就会减少,导致代码出错。
当然如果在循环前保存了queue.size(),也可以从0开始遍历,如下所示。

int size = queue.size();
for(int i = 0;i < queue.size();i++)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WFForstar

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值