算法通过村第七关-树(递归/二叉树遍历)白银笔记|递归实战

文章目录

  • 前言
  • 1. 深入理解前中后序遍历
    • 从小到大递推
    • 分情况讨论,明确结束条件
    • 组合出完整的方法:
    • 从大到小 画图推演
  • 总结


前言


提示:没有客观公正的记忆这回事,所有的记忆都是偏见,都是为自己的存活而重组过的经验。--国强生《断代》

1. 深入理解前中后序遍历

深度优先遍历有前中后序三种情况,大部分人看过后就可以写出来,但是很多人只是记住了代码结构,稍微改变一下就废了。这就是头疼的地方。

我们再从二叉树的角度看递归,每次遇到递归,都是按照前面说的四步骤来写,可以更好的写出正确的递归算法。通过二叉树可以非常方便的理解递归,递归只是处理当前这一层和下一层之间的关系,并不关系下层和下下层之间的关系,就好比护犊子这个词,比护孙子提起来顺口。不常用也不掺和。具体我们再强调一下着四步:

  1. 从小到大递推
  2. 分情况讨论,明确结束条件
  3. 组合出完整方法
  4. 想验证,则从大到小画图推演

我们接下来就一步一步看看怎么操作:

从小到大递推

我们从一个二叉树为例:

	39     2015    6

我们找一个小部分,最小的子树:

	   20 15     6

假如20为head,则此时前序访问顺序应该是:

public void visit() {list.add(root);// 20被访问root.left; // 继续访问15root.right; // 继续访问7
}

然后再往上看,node(3)的情况:

public void visit() {list.add(root);// 3被访问root.left; // 继续访问9root.right; // 继续访问20
}

这里的20 是一个子树的父节点,访问方式与上面的访问一样,我们就直接把他们合并在一起:

public void visit() {list.add(root);// 20被访问visit(root.left); // 继续访问15visit(root.right); // 继续访问7
}

这就是我们期待的递归方法。

分情况讨论,明确结束条件

上面我们已经总结出了递归的主体,但是这个递归在什么时候结束呢?很明显root == null的时候停驶。一般来说链表和二叉树问题的终止条件都包含当前访问元素为null。有些题目结束条件复杂也是有的,此时最好的方法就是

将可能结束的情况列举出来,然后整理一下就可以了,这个我们接着往下看。

组合出完整的方法:

到目前位置:我们就可以整理出完整的代码,同时为了方便区分,我们将方法名换成perorder:

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

从大到小 画图推演

写完之后不要觉得就万事大吉了?递归的方法很难调试的,即使对的,你也可能会晕,这里介绍一种简单的验证方法–调用过程图法。我们可以画几个过程图看一看,因为是递归函数,如果比较复杂我们可以少画几组。

递归的特征是“不撞南墙不回头”,一定是在执行到某个root==null才开始返回的,如下图:
在这里插入图片描述
从图中可以看到,当root的一个子树为null的时候就不会继续执行递归,进入之后发现root == null,就看是返回了。这里要注意res.add()的时机,将其进入顺序一次写出来就是我们需要的结果。该过程明确之后在debug就很容易,刚开始学习递归我建议多画几次,熟悉之后就不必再画图了。

前序遍历写出来之后,中序和后序遍历就不是很难了,中序是左中右,后序时左右中。代码如下:

// 中序遍历
public void inOrderRecur(TreeNode root,List<Integer> res) {if(root == null){return ;}perorder(root.left,res); Sysytem.out.print(root.val + " ");perorder(root.right,res); 
}

// 后续遍历
public void postOrderRecur(TreeNode root,List<Integer> res) {if(root == null){return ;}perorder(root.left,res); perorder(root.right,res); Sysytem.out.print(root.val + " ");
}

另外需要注意的是:

面试和力扣的上面提供的方法可能不能直接用来递归,需要我们在常创建一个方法:

例如:144. 二叉树的前序遍历 - 力扣(LeetCode)
在这里插入图片描述
在这里插入图片描述
现在看到这个题目就很简单吧🥰:

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

总结

提示:图解递归;二叉树递归遍历;怎么写好递归

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/109037.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot 自动装配原理

一.原理解释 Spring Boot的自动配置是Spring框架的一个重要特性&#xff0c;它旨在简化应用程序的开发和部署过程。自动配置通过基于类路径中的依赖关系和配置文件内容来预先配置Spring应用程序的各种组件和功能。这样&#xff0c;我们可以在无需显式配置大量参数的情况下&…

慢查询SQL如何优化

一.什么是慢SQL? 慢SQL指的是Mysql中执行比较慢的SQL,排查慢SQL最常用的方法是通过慢查询日志来查找慢SQL。Mysql的慢查询日志是Mysql提供的一种日志记录&#xff0c;它用来记录Mysql中响应时间超过long_query_time值的sql,long_query_time的默认时间为10s. 二.查看慢SQL是否…

机器学习——贝叶斯(三种分布)/鸢尾花分类分界图/文本分类应用

0、前言&#xff1a; 机器学习中的贝叶斯的理论基础是数学当中的贝叶斯公式。这篇博客强调使用方法&#xff0c;至于理论未作深究。机器学习中三种类型的贝叶斯公式&#xff1a;高斯分布&#xff08;多分类&#xff09;、多项式分布&#xff08;文本分类&#xff09;、伯努利分…

Spring的 webFlux 和 webMVC

看到一个测评文章&#xff0c;并发在300的时候webMVC 和 webFlux的处理能力不相上下&#xff0c; 当并发达到3000的时候, webFlux明显优于webMVC, 有图有真相&#xff0c; 我信了. webMVC 是 one-request-one thread 堵塞模式, flux是非阻塞模式&#xff0c; 是spring家族系列…

分布式运用之rsync远程同步

一、rsync的相关知识 1.1 rsync简介 rsync&#xff08;Remote Sync&#xff0c;远程同步&#xff09;是一个开源的快速备份工具&#xff0c;可以在不同主机之间镜像同步整个目录树&#xff0c;支持增量备份&#xff0c;并保持链接和权限&#xff0c;且采用优化的同步算法&am…

GaussDB(DWS)云原生数仓技术解析:湖仓一体,体验与大数据互联互通

文章目录 前言一、关于数据仓库需求场景分类二、数据仓库线下部署场景2.1、线下部署场景介绍及优劣势说明2.2、线下部署场景对应的客户需求 三、数据仓库公有云部署场景3.1、公有云部署场景介绍及优劣势说明3.2、公有云部署场景对应的客户需求 四、为何重视数据共享&#xff08…

Python编程指南:利用HTTP和HTTPS适配器实现智能路由

嗨&#xff0c;爬虫大佬们&#xff01;今天我要为大家分享一篇关于如何利用HTTP和HTTPS适配器来实现智能路由的Python编程指南。在现代互联网应用中&#xff0c;路由功能起着至关重要的作用&#xff0c;而利用Python编程语言实现智能路由则可以为我们的应用带来更高的灵活性和性…

一阶微分方程

目录 可分离变量的方程 齐次微分方程 一阶线性微分方程 伯努科方程 全微分方程 可分离变量的方程 可分离变量的方程是一种常见的一阶常微分方程类型&#xff0c;其特点是可以通过将变量分离到方程的两侧&#xff0c;从而可以分别对各自变量进行积分。一般形式的可分离变量…

企业架构LNMP学习笔记45

失效机制&#xff08;了解&#xff09; 1&#xff09;如果key过期了&#xff0c;value会及时删除么&#xff1f;空间会及时清理么&#xff1f; 2&#xff09;如果分配的存储空间&#xff0c;写满了&#xff0c;还允许写么&#xff1f; -m可以配置内存大小。 memcached 内部不…

第14章_瑞萨MCU零基础入门系列教程之QSPI

本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写&#xff0c;需要的同学可以在这里获取&#xff1a; https://item.taobao.com/item.htm?id728461040949 配套资料获取&#xff1a;https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总&#xff1a; ht…

火山引擎边缘云助力智能科技赋予生活更多新意

当下&#xff0c;先进的科学技术使得我们的日常生活变得快捷、舒适。大到上百层智能大厦、高端公共场所、社会智能基础设施&#xff0c;小到智能家居监控、指纹密码锁等&#xff0c;在这个充满想象力的时代&#xff0c;科技以更加智能化的方式改变和守护我们的生活。 引入智能…

一线大厂Redis高并发缓存架构实战与性能优化

多级缓存架构 缓存设计 缓存穿透 缓存穿透是指查询一个根本不存在的数据&#xff0c; 缓存层和存储层都不会命中&#xff0c; 通常出于容错的考虑&#xff0c; 如果从存储层查不到数据则不写入缓存层。 缓存穿透将导致不存在的数据每次请求都要到存储层去查询&#xff0c; 失…