目录
一、二叉树理论基础
二、递归遍历思路
三、相关算法题目
四、总结
二叉树是一种基本数据结构,TreeMap 和 TreeSet的底层实现使用了红黑树;
基础知识详见:代码随想录 (programmercarl.com)
1.二叉树的种类:完全二叉树、平衡二叉搜索树、满二叉树、二叉搜索树
2.二叉树的遍历方式:深度优先遍历(前序遍历、中序遍历、后序遍历)、广度优先遍历(层次遍历)
3.二叉树的存储方式:顺序存储(数组、层次遍历)、链式存储(链表)(常用)
4.二叉树的定义:链式存储二叉树结点的定义
public class TreeNode{
int val;
TreeNode left;
TreeNode right;
public TreeNode(){}
public TreeNode(int val){
this.val = val;
}
public TreeNode(int val, TreeNode left, TreeNode right){
this.val = val;
this.left = left;
this.right = right;
}
}
递归算法三步骤(参考代码随想录,详见代码随想录 (programmercarl.com)
以前序遍历为例:
1.确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。
前序遍历中,需要一个根节点来处理,一个数组来存储遍历后的结果,共两个参数,那么此时返回值就可以为void;
2.确定终止条件:运行的时候,经常会遇到栈溢出的错误,一般是没写终止条件或者终止条件写的不对,操作系统是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。
前序遍历中,终止条件就是被操作结点此时为空;
3.确定单层递归的逻辑:确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。
前序遍历顺序是中左右,单层逻辑为:①添加中间结点到数组;②对当前结点的左子结点调用递归函数,遍历左子树;③对当前结点的右子结点调用递归函数,遍历右子树;
同理,后序遍历的逻辑顺序为:②③①
中序遍历的逻辑顺序为:②①③
144.二叉树的前序遍历
class Solution {
public List preorderTraversal(TreeNode root) {
List list = new ArrayList<>();
preTraver(root, list);
return list;
}
public void preTraver(TreeNode root, List list){
if(root == null) return; //终止条件
list.add(root.val); //中间结点
preTraver(root.left, list); //左边节点
preTraver(root.right, list); //右边节点
}
}
class Solution {
List list = new ArrayList<>();
public List preorderTraversal(TreeNode root) {
if(root == null) return list;
list.add(root.val);//中间结点
preorderTraversal(root.left);//左边结点
preorderTraversal(root.right);//右边节点
return list;
}
}
递归函数在调用时,会保存当前状态,进入下一层递归;当递归返回时,程序会回到调用它的地方,继续执行后续代码;
第一个return list:递归函数的终止条件,如果结点为空,直接返回当前结果,不再继续递归;
第二个return list:返回每一次递归函数的最终结果,同时也会返回到上一层递归;
145.二叉树的后序遍历
class Solution {
public List postorderTraversal(TreeNode root) {
List list = new ArrayList<>();
postTraver(root, list);
return list;
}
public void postTraver(TreeNode root, List list){
if(root == null) return;
postTraver(root.left, list); //左节点
postTraver(root.right, list);//右节点
list.add(root.val);//中间结点
}
}
94.二叉树的中序遍历
class Solution {
public List inorderTraversal(TreeNode root) {
List list = new ArrayList<>();
inTraver(root, list);
return list;
}
public void inTraver(TreeNode root, List list){
if(root == null) return; //终止条件
inTraver(root.left, list); //左节点
list.add(root.val); //中间结点
inTraver(root.right, list); //右节点
}
}
1.二叉树的三种深度遍历和一种广度遍历方式;
2.几种常见的二叉树的定义;
3.二叉树结点定义的代码书写;
4.由二叉树递归遍历掌握递归算法的三个步骤,如何写递归算法;