那么链式存储⽅式就⽤指针, 顺序存储的⽅式就是⽤数组。
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
二叉树的遍历方式 : 递归,迭代(栈), 迭代(栈,统一写法)共9种
迭代(栈,统一写法)模板:以前序遍历为例。
//二叉树的前序遍历(迭代: 统一写法)
class Solution {
public List preorderTraversal(TreeNode root) {
List ans = new ArrayList<>();
Stack stack = new Stack<>();
if(root != null){
stack.push(root);
}
while(!stack.isEmpty()){
TreeNode node = stack.pop();//取出栈顶元素
if(node != null){
if(node.right != null){
stack.push(node.right);//添加右节点
}
if(node.left != null){
stack.push(node.left);//添加左节点
}
stack.push(node);//添加中节点
stack.push(null);//中节点访问过,但是还没有处理,加入空节点作为标记
}else{//只有遇到空节点(标志位)的时候,才将下一个节点放进结果集
node = stack.pop();//重新取出栈中元素
ans.add(node.val);
}
}
return ans;
}
}
⼆叉树的层序遍历
//广度优先遍历 队列
class Solution {
public List> levelOrder(TreeNode root) {
List> ans = new ArrayList<>();
Queue queue = new LinkedList<>();
if(root != null){
queue.offer(root);//添加元素offer 弹出元素 poll
}
while(!queue.isEmpty()){
int size = queue.size();
List res = new ArrayList<>();
for(int i=0;i
对称⼆叉树:
递归:后序,⽐较的是根节点的左⼦树与右⼦树是不是相互翻转迭代:使⽤队列 / 栈将两个节点顺序放⼊容器中进⾏⽐较
⼆叉树的最⼤深度:
递归:后序,求根节点最⼤⾼度就是最⼤深度,通过递归函数的返回值做计算树的⾼度迭代:层序遍历
104.⼆叉树的最⼤深度
题⽬地址:https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/
559.N叉树的最⼤深度
题⽬地址:https://leetcode-cn.com/problems/maximum-depth-of-n-ary-tree/
⼆叉树的最⼩深度:
递归:后序,求根节点最⼩⾼度就是最⼩深度,注意最⼩深度的定义迭代:层序遍历
完全⼆叉树的节点个数 :
递归:后序,通过递归函数的返回值计算节点数ᰁ迭代:层序遍历
222.完全⼆叉树的节点个数
题⽬地址:https://leetcode-cn.com/problems/count-complete-tree-nodes/
平衡⼆叉树:
递归:后序,注意后序求⾼度和前序求深度,递归过程判断⾼度差迭代:效率很低,不推荐
110.平衡⼆叉树
题⽬地址:https://leetcode-cn.com/problems/balanced-binary-tree/
高度和深度:根节点的⾼度就是这颗树的最⼤深度
求深度可以从上到下去查 所以需要前序遍历(中左右),⽽⾼度只能从下到上去查,所以只能后序遍历(左右中)
⼆叉树的所有路径:
递归:前序,⽅便让⽗节点指向⼦节点,涉及回溯处理根节点到叶⼦的所有路径迭代:⼀个栈模拟递归,⼀个栈来存放对应的遍历路径
257. ⼆叉树的所有路径
题⽬地址:https://leetcode-cn.com/problems/binary-tree-paths/
左叶⼦之和:
递归:后序,必须三层约束条件,才能判断是否是左叶⼦。迭代:直接模拟后序遍历
树左下⻆的值:
递归:顺序⽆所谓,优先左孩⼦搜索,同时找深度最⼤的叶⼦节点。迭代:层序遍历找最后⼀⾏最左边
513.找树左下⻆的值
题⽬地址:https://leetcode-cn.com/problems/find-bottom-left-tree-value/
如果需要遍历整颗树,递归函数就不能有返回值。如果需要遍历某⼀条固定路线,递归函数就⼀定要有返回值!
路径总和:
递归:顺序⽆所谓,递归函数返回值为 bool 类型是为了搜索⼀条边,没有返回值是搜索整棵树。迭代:栈⾥元素不仅要记录节点指针,还要记录从头结点到该节点的路径数值总和
112. 路径总和
题⽬地址:https://leetcode-cn.com/problems/path-sum/
113. 路径总和II
题⽬地址:https://leetcode-cn.com/problems/path-sum-ii/
翻转⼆叉树:
递归:前序,交换左右孩⼦迭代:直接模拟前序遍历
构造⼆叉树登场:
递归:前序,重点在于找分割点,分左右区间构造迭代:⽐较复杂,意义不⼤
106.从中序与后序遍历序列构造⼆叉树
题⽬地址:https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/
105.从前序与中序遍历序列构造⼆叉树
题⽬地址:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
构造⼀棵最⼤的⼆叉树:
递归:前序,分割点为数组最⼤值,分左右区间构造迭代:⽐较复杂,意义不⼤
654.最⼤⼆叉树
题⽬地址:https://leetcode-cn.com/problems/maximum-binary-tree/
合并两个⼆叉树:
递归:前序,同时操作两个树的节点,注意合并的规则迭代:使⽤队列,类似层序遍历
⼆叉搜索树中的搜索:
递归:⼆叉搜索树的递归是有⽅向的迭代:因为有⽅向,所以迭代法很简单
验证⼆叉搜索树:
递归:中序,相当于变成了判断⼀个序列是不是递增的迭代:模拟中序,逻辑相同
98.验证⼆叉搜索树
题⽬地址:https://leetcode-cn.com/problems/validate-binary-search-tree/
注意⼆叉搜索树中不能有重复元素
(⼆叉搜索树的特性)⼆叉搜索树的最⼩绝对差:
递归:中序,双指针操作迭代:模拟中序,逻辑相同
⼆叉搜索树中的众数:
递归:中序,清空结果集的技巧,遍历⼀遍便可求众数集合迭代:模拟中序,逻辑相同
把⼆叉搜索树转换为累加树:
递归:中序,双指针操作累加迭代:模拟中序,逻辑相同
⼆叉树的最近公共祖先:
递归:后序,回溯,找到左⼦树出现⽬标值,右⼦树节点⽬标值的节点。迭代:不适合模拟回溯
236. ⼆叉树的最近公共祖先
题⽬链接:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/
⼆叉搜索树的最近公共祖先:
递归:顺序⽆所谓,如果节点的数值在⽬标区间就是最近公共祖先迭代:按序遍历
235. ⼆叉搜索树的最近公共祖先
⼆叉搜索树中的插⼊操作:
递归:顺序⽆所谓,通过递归函数返回值添加节点迭代:按序遍历,需要记录插⼊⽗节点,这样才能做插⼊操作
删除⼆叉搜索树中的节点:
递归:前序,想清楚删除⾮叶⼦节点的情况迭代:有序遍历,较复杂
修剪⼆叉搜索树:
递归:前序,通过递归函数返回值删除节点迭代:有序遍历,较复杂
构造⼀棵⼆叉搜索树:
递归:前序,数组中间节点分割迭代:较复杂,通过三个队列来模拟