博客
关于我
144. 二叉树的前序遍历
阅读量:262 次
发布时间:2019-03-01

本文共 4202 字,大约阅读时间需要 14 分钟。

二叉树的前序遍历

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

示例:

输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,2,3]

思路+代码+注释:

public List preorderTraversal(TreeNode root) { List res=new ArrayList preorderTraversal(root,res); return res; }

private void preorderTraversal(TreeNode node,List res) { if (node==null) { return; } res.add(node.val); preorderTraversal(node.left,res); preorderTraversal(node.right,res); }

代码解释:

前序遍历的思路是根→左→右。我们采用递归的方式来处理树的节点。当节点为null时,直接返回;当节点不为null时,将节点的值添加到res中,然后递归处理左子节点,最后递归处理右子节点。

示例分析:

输入的二叉树结构如下: 1 /

2 3

前序遍历的结果是:1→2→3

代码实现:

使用递归的方式,先处理当前节点的值,然后递归处理左子节点,最后递归处理右子节点。

代码注释:

public List preorderTraversal(TreeNode root) { List res=new ArrayList preorderTraversal(root,res); return res; }

private void preorderTraversal(TreeNode node,List res) { if (node==null) { return; } res.add(node.val); preorderTraversal(node.left,res); preorderTraversal(node.right,res); }

代码解释:

  • 首先,在函数 preorderTraversal 中,创建一个空的列表 res,以备存储结果。
  • 调用递归函数 preorderTraversal,传入根节点和 res。
  • 递归函数 preorderTraversal 检查当前节点是否为 null。如果是 null,直接返回。
  • 如果当前节点不为 null,将节点的值添加到 res 中。
  • 递归处理左子节点。
  • 递归处理右子节点。
  • 示例输出:

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

    代码实现的核心思想是利用递归来实现前序遍历的顺序,即先处理根节点,再处理左子节点,最后处理右子节点。

    代码优化:

    为了提高代码的可读性和性能,可以优化代码如下:

    public List preorderTraversal(TreeNode root) { List res=new ArrayList if (root != null) { res.add(root.val); preorderTraversal(root.left, res); preorderTraversal(root.right, res); } return res; }

    private void preorderTraversal(TreeNode node,List res) { if (node == null) { return; } res.add(node.val); preorderTraversal(node.left, res); preorderTraversal(node.right, res); }

    这一优化可以减少一些无用的检查,使代码更加简洁。

    代码注释优化:

    为了让代码更易理解,可以添加更详细的注释:

    public List preorderTraversal(TreeNode root) { /* * 返回二叉树的前序遍历结果 * @param root 二叉树的根节点 * @return 前序遍历结果的列表 / List res=new ArrayList / * 如果根节点不为空,将其值添加到结果列表中 * 然后递归处理左子节点,最后递归处理右子节点 */ if (root != null) { res.add(root.val); preorderTraversal(root.left, res); preorderTraversal(root.right, res); } return res; }

    private void preorderTraversal(TreeNode node,List res) { /* * 如果当前节点为空,直接返回 / if (node == null) { return; } / * 将当前节点的值添加到结果列表中 / res.add(node.val); / * 递归处理左子节点 / preorderTraversal(node.left, res); / * 递归处理右子节点 */ preorderTraversal(node.right, res); }

    代码优化后的注释更加详细,方便开发者理解。

    示例测试:

    测试输入:root = [1,null,2,3] 测试输出:[1,2,3]

    代码运行结果:

    调用 preorderTraversal(1, res) → res.add(1) 调用 preorderTraversal(null, res) → 返回 调用 preorderTraversal(2, res) → res.add(2) 调用 preorderTraversal(null, res) → 返回 调用 preorderTraversal(3, res) → res.add(3) 调用 preorderTraversal(null, res) → 返回

    最终 res = [1,2,3]

    代码性能:

    该算法的时间复杂度为 O(n),其中 n 是二叉树的节点数。空间复杂度为 O(h),h 是二叉树的高度。

    代码适用范围:

    该算法适用于所有二叉树的前序遍历问题,包括二叉树的子树前序遍历、偶数层序遍历等。

    代码扩展:

    如果需要对二叉树的其他遍历方式进行实现,可以参考以下代码:

    • 中序遍历: public List inorderTraversal(TreeNode root) { List res=new ArrayList inorderTraversal(root, res); return res; }

      private void inorderTraversal(TreeNode node,List res) { if (node == null) { return; } inorderTraversal(node.left, res); res.add(node.val); inorderTraversal(node.right, res); }

    • 后序遍历: public List postorderTraversal(TreeNode root) { List res=new ArrayList postorderTraversal(root, res); return res; }

      private void postorderTraversal(TreeNode node,List res) { if (node == null) { return; } postorderTraversal(node.left, res); postorderTraversal(node.right, res); res.add(node.val); }

    通过这种方式,可以轻松扩展对不同遍历方式的实现。

    代码总结:

    前序遍历是处理根节点,然后处理左子节点,最后处理右子节点。通过递归的方式,可以实现二叉树的前序遍历。

    代码优化建议:

    为了提高代码性能,可以使用循环实现前序遍历,而不是递归。递归在处理非常深的二叉树时,可能会导致栈溢出问题。

    代码实战:

    在实际开发中,可以将二叉树的节点用 JavaBean 标签表示,如:

    然后通过 Spring 的配置来定义二叉树的结构。这样可以简化代码配置,方便测试和调试。

    代码测试:

    在测试代码时,可以使用以下方式验证结果是否正确:

    public static void main(String[] args) { TreeNode root = new TreeNode(1); root.left = new TreeNode(2); root.right = new TreeNode(3); List result = preorderTraversal(root); System.out.println(result); // 输出 [1,2,3] }

    通过以上代码,可以验证前序遍历的正确性。

    代码优化:

    为了提高代码性能,可以将递归方法改为循环方法。例如:

    public List preorderTraversal(TreeNode root) { List res=new ArrayList Stack stack=new Stack() if (root != null) { stack.push(root); } while (!stack.isEmpty()) { TreeNode node = stack.pop(); res.add(node.val); if (node.right != null) { stack.push(node.right); } if (node.left != null) { stack.push(node.left); } } return res; }

    这种方法使用栈来模拟递归的过程,避免了递归调用的开销。

    代码总结:

    通过以上代码和优化,可以清晰地看到如何实现二叉树的前序遍历。递归和循环两种方法都可以实现,建议根据实际需求选择合适的方式。

    通过以上优化,可以确保代码的可读性、性能和可扩展性。

    转载地址:http://ppwa.baihongyu.com/

    你可能感兴趣的文章
    NLog类库使用探索——详解配置
    查看>>
    NLP 基于kashgari和BERT实现中文命名实体识别(NER)
    查看>>
    NLP 模型中的偏差和公平性检测
    查看>>
    Vue3.0 性能提升主要是通过哪几方面体现的?
    查看>>
    NLP 项目:维基百科文章爬虫和分类【01】 - 语料库阅读器
    查看>>
    NLP_什么是统计语言模型_条件概率的链式法则_n元统计语言模型_马尔科夫链_数据稀疏(出现了词库中没有的词)_统计语言模型的平滑策略---人工智能工作笔记0035
    查看>>
    NLP三大特征抽取器:CNN、RNN与Transformer全面解析
    查看>>
    NLP学习笔记:使用 Python 进行NLTK
    查看>>
    NLP度量指标BELU真的完美么?
    查看>>
    NLP的不同研究领域和最新发展的概述
    查看>>
    NLP的神经网络训练的新模式
    查看>>
    NLP采用Bert进行简单文本情感分类
    查看>>
    NLP问答系统:使用 Deepset SQUAD 和 SQuAD v2 度量评估
    查看>>
    NLP项目:维基百科文章爬虫和分类【02】 - 语料库转换管道
    查看>>
    NLP:使用 SciKit Learn 的文本矢量化方法
    查看>>
    nmap 使用方法详细介绍
    查看>>
    Nmap扫描教程之Nmap基础知识
    查看>>
    nmap指纹识别要点以及又快又准之方法
    查看>>
    Nmap渗透测试指南之指纹识别与探测、伺机而动
    查看>>
    Nmap端口扫描工具Windows安装和命令大全(非常详细)零基础入门到精通,收藏这篇就够了
    查看>>