前言
二叉树是数据结构中使用频率非常高的一种了,凭借高实用性和效率成为数据结构中必须攻克的一环。关于二叉树的问题,说简单其实也很简单,只要摸清根与左右节点之间的关系,套用二叉树的遍历框架就能解决;说难倒也难,简单的题很容易发现这种关系,难题就不一定了。
本文先从二叉树的基本思想出发,给出二叉树的套用框架,再根据实际的二叉树题目来具体说明如何应用。当然,由于篇幅限制,不可能将每道题都说明,因此,本文将从leetcode
的二叉树问题中挑选2道简单题,1道中等题,讲解如何解决二叉树基本问题。
题不在多,关键是掌握解决题目的思想和思路,同时由于我刷的题目还比较少,后期会添加一些比较特殊的二叉树难题解决思路到本文中。
二叉树的基本思想
讲二叉树,首先要理解什么是二叉树,下面是我绘制的一幅二叉树图像。
显然,二叉树包含根节点和左右两个子节点。所有的操作都是围绕这三者展开,例如我们本科数据结构与算法常讲的前、中、后序遍历。本质上就是根节点处理相对于左右节点的位置。转换成图形思想就如下图所示:
红色:最先遍历,橙色:第二个遍历,黄色:最后遍历
我们同样也可以将其转换成代码的形式:
void traverse(root):
// root在此,前序
traverse(root.left)
// root在此,中序
traverse(root.right)
// root在此,后序
上面我只画了三个节点,因此容易被忽略的一点是:实际操作是针对root节点进行的,在这里,实际操作就是traverse
这个函数,因此,在我们处理了root
之后去处理root.left
的时候,root.left
就成了新的root
,也就是说当前root.right
必须得等root.left
作为root
的子树处理完了才能处理,体现在遍历上就是最后打印。
所谓万变不离其宗,二叉树的所有问题基本上离不开遍历的思想,我们对二叉树的操作,无非增删改查
,这就涉及到对每个节点的处理,而对每个节点的处理可以转换成root
,root.left
,root.right
的处理,继续不断发散,其实就是递归的思想。
当完全掌握二叉树的用法后,对于递归问题也能够驾轻就熟
简单题
下面直接从具体的问题入手,我选择了leetcode
上两道简单的二叉树问题。
大部分思想是异曲同工的,有些东西我可能总结并不到位,需要自己举一反三
合并二叉树
这种问题直接套用遍历的框架,加一点判断条件即可。
-
问题描述
-
解决思路
问题很好理解,就是两棵二叉树对应位置相加,也就是说我们要对两棵树的每个位置都对应查看。说白了将两棵树缺失的位置补0,再叠到一块就好了。那么如何向我们的遍历框架靠拢呢?其实很好解决,全部位置的叠加我们只需要转换成根节点的叠加,剩下的扔给左右子节点考虑。可以快速写出代码如下:
class TreeNode(object): # 树的定义 def __init__(self, x): self.val = x self.left = None se