二叉树的递归都要多看卡哥视频去领悟真谛!!!
目录
统一迭代 (基础不好的录友,迭代法可以放过),一刷直接放过了,二刷有精力在看!!!
理论基础
需要了解 二叉树的种类,存储方式,遍历方式 以及二叉树的定义
文章讲解:代码随想录
递归遍历 (必须掌握)
二叉树的三种递归遍历掌握其规律后,其实很简单
题目链接/文章讲解/视频讲解:代码随想录,这里多看卡哥视频!!!
题解思路:
144.二叉树的前序遍历(递归实现)代码如下:
/**
* Definition for a binary tree node.
* 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;
* }
* }
*/
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
traverse(root, result);
return result;
}
public void traverse(TreeNode root, List<Integer> result){
TreeNode current = root;
if(current == null){
return;
}
result.add(current.val); //中
traverse(current.left, result); //左
traverse(current.right, result); //右
}
}
145.二叉树的后序遍历(递归实现)代码如下:
/**
* Definition for a binary tree node.
* 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;
* }
* }
*/
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
postTraverse(root, result);
return result;
}
public void postTraverse(TreeNode root, List<Integer> result){ //后序遍历:左右中
TreeNode current = root;
if(current == null){
return;
}
postTraverse(current.left, result); //左
postTraverse(current.right, result); //右
result.add(current.val); //中
}
}
94.二叉树的中序遍历(递归实现)代码如下:
/**
* Definition for a binary tree node.
* 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;
* }
* }
*/
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
inTraverse(root, result);
return result;
}
public void inTraverse(TreeNode root, List<Integer> result){ //左中右
TreeNode current = root;
if(current == null){
return;
}
inTraverse(current.left, result);
result.add(current.val);
inTraverse(current.right, result);
}
}
迭代遍历 (基础不好的录友,迭代法可以放过)
题目链接/文章讲解/视频讲解:代码随想录
题解思路:
144.二叉树的前序遍历(迭代遍历)代码如下:
前序遍历的迭代实现方法,这里卡哥视频说的也很详细,注意卡哥视频里面说的往栈中添加左右节点的顺序!!!前序遍历属于深度优先算法,每次传入节点后先把该节点的val值存储到结果集合中,然后会先一直遍历到其所在节点的左右节点都是null值后,再往回去遍历他的左右节点
/**
* Definition for a binary tree node.
* 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;
* }
* }
*/
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
Stack<TreeNode> stack = new Stack<>(); //用来暂存二叉树的节点
List<Integer> result = new ArrayList<>(); //用来存放结果的集合
stack.push(root); //先将根节点压入栈中,然后再以根节点的left和rigth属性去遍历他的左子树和右子树
while(!stack.empty()){ //由于对栈进行添加和弹出元素,因此栈要非null才可以操作
TreeNode stackTop = stack.pop(); //把栈顶的元素弹出
if(stackTop != null){ //中:因为一开始传进去的就是位于中间的根节点,如果栈顶元素不是null值,则把节点的val值添加到结果集合中
result.add(stackTop.val);
}else{
continue; //如果栈顶元素是null值则进行下一次循环,会不断的迭代到压入栈中的那一层节点不是null值,然后等到把节点都弹出才结束循环
}
stack.push(stackTop.right); //左:前序遍历属于深度优先算法,会一直往栈中传入他的右节点,一直到null值为值,然后在if语句中continue再往回
stack.push(stackTop.left); //右:前序遍历属于深度优先算法,会一直往栈中传入他的左节点,一直到null值为值,然后在if语句中continue再往回
}
return result;
}
}
145.二叉树的后序遍历(迭代实现)代码如下:
听卡哥视频,说文字很容易绕晕,卡哥这里说的后序迭代实现方法只要在前序迭代实现方法中修改三行代码即可实现!!!多听卡哥视频YYDS!!!
/**
* Definition for a binary tree node.
* 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;
* }
* }
*/
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
Stack<TreeNode> stack = new Stack<>(); //用来暂存二叉树的节点
List<Integer> result = new ArrayList<>(); //用来存放结果的集合
stack.push(root); //先将根节点压入栈中,然后再以根节点的left和rigth属性去遍历他的左子树和右子树
while(!stack.empty()){ //由于对栈进行添加和弹出元素,因此栈要非null才可以操作
TreeNode stackTop = stack.pop(); //把栈顶的元素弹出
if(stackTop != null){ //中:因为一开始传进去的就是位于中间的根节点,如果栈顶元素不是null值,则把节点的val值添加到结果集合中
result.add(stackTop.val);
}else{
continue; //如果栈顶元素是null值则进行下一次循环,会不断的迭代到压入栈中的那一层节点不是null值,然后等到把节点都弹出才结束循环
}
stack.push(stackTop.left); //右:前序遍历属于深度优先算法,会一直往栈中传入他的左节点,一直到null值为值,然后在if语句中continue再往回
stack.push(stackTop.right); //左:前序遍历属于深度优先算法,会一直往栈中传入他的右节点,一直到null值为值,然后在if语句中continue再往回
}
reverse(result);
return result;
}
public void reverse(List<Integer> list){
for(int start = 0, end = list.size() - 1; start < end; start++, end--){
int temp = list.get(start);
list.set(start, list.get(end));
list.set(end, temp);
}
}
}
94.二叉树的中序遍历(迭代实现)代码如下:
多听卡哥视频,把思路捋清楚去走一遍过程,卡哥说的很详细了已经!!!多听多看题解,把思路扶正!!!
/**
* Definition for a binary tree node.
* 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;
* }
* }
*/
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
Stack<TreeNode> st = new Stack<>();
TreeNode current = root;
if(current == null){
return result;
}
while(current != null || !st.empty()){ //只有当current为空和栈为空的时候才结束循环,否则只要其中一个不为空,就需要继续遍历迭代下去
if(current != null){
st.push(current);
current = current.left;
}else{
TreeNode stTop = st.pop();
result.add(stTop.val);
current = stTop.right; //当需要遍历右子树时,当前节点应该被设置为当前节点的右孩子
}
}
return result;
}
}
统一迭代 (基础不好的录友,迭代法可以放过),一刷直接放过了,二刷有精力在看!!!
这是统一迭代法的写法, 如果学有余力,可以掌握一下
题目链接/文章讲解:代码随想录