本篇文章给大家分享一下二叉树的相关算法。

力扣(LeetCode)刷题第144和114题:二叉树的遍历和相关操作!_数据结构

前言

​题目地址(难度:简单):二叉树前序遍历​

​题目地址(难度:中等): 二叉树展开为链表​

一、题目介绍

1.1二叉树前序遍历

我们都知道二叉树有三种遍历方式,分别是前序遍历、中序遍历和后序遍历,每一种遍历都有不同的性质,大家在后期的做题过程中可能会用到一些遍历的性质,所以请注意这块的性质!

三种遍历都是类似的,就是输出的顺序有所不同,会一种基本其余的两种也就会写了。

示例 1:

输入:root = [1,null,2,3]
输出:[1,2,3]

示例 2:

输入:root = []
输出:[]

1.2 二叉树展开为链表

给定一个二叉树,原地将它展开为一个单链表。其实仔细分析题目,这就是前序输出二叉树,这里介绍的也是最容易想到的思路,官方还给了另外的两种思路,大家可以到​​这里查看!​

示例 1:

力扣(LeetCode)刷题第144和114题:二叉树的遍历和相关操作!_二叉树_02

二、解题思路

1.分析题目

当拿到二叉树类型的题目的时候,就要往这方面的内容进行思考,比如三种遍历方式、还有就是深度优先搜索和广度优先搜索这块思考,基本常见的也就是这几种题目。

2.二叉树的前序遍历

对于二叉树的前序遍历,我们可以使用递归和迭代的方式进行遍历。

2.2.1递归

class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
preorder(root, res);//递归调用
return res;
}

public void preorder(TreeNode root, List<Integer> res) {
if (root == null) {
return;
}
res.add(root.val);//根节点
preorder(root.left, res);//左子树
preorder(root.right, res);//右子树
}
}

复杂度分析


  • 时间复杂度:O(n)O(n),其中 nn 是二叉树的节点数。每一个节点恰好被遍历一次。
  • 空间复杂度:O(n)O(n),为递归过程中栈的开销,平均情况下为 O(\log n)O(logn),最坏情况下树呈现链状,为
    O(n)O(n)。

2.2.2迭代

class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if (root == null) {
return res;
}

Deque<TreeNode> stack = new LinkedList<TreeNode>();
TreeNode node = root;
while (!stack.isEmpty() || node != null) {
while (node != null) {
res.add(node.val);
stack.push(node);
node = node.left;
}
node = stack.pop();
node = node.right;
}
return res;
}
}

复杂度分析


  • 时间复杂度:O(n)O(n),其中 nn 是二叉树的节点数。每一个节点恰好被遍历一次。
  • 空间复杂度:O(n)O(n),为迭代过程中显式栈的开销,平均情况下为 O(\log n)O(logn),最坏情况下树呈现链状,为
    O(n)O(n)。

3.代码

3.1题目一:二叉树前序遍历

Java代码详细注释

class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();//创建list
preTree(root,result);//递归遍历
return result;
}
public void preTree(TreeNode root,List<Integer> result){
if(root!=null){
result.add(root.val);
preTree(root.left,result);
preTree(root.right,result);
}
}
}

3.2题目二: 二叉树展开为链表

将二叉树展开为单链表之后,单链表中的节点顺序即为二叉树的前序遍历访问各节点的顺序。因此,可以对二叉树进行前序遍历,获得各节点被访问到的顺序。由于将二叉树展开为链表之后会破坏二叉树的结构,因此在前序遍历结束之后更新每个节点的左右子节点的信息,将二叉树展开为单链表。

Java代码详细注释

class Solution {
public void flatten(TreeNode root) {
List<TreeNode> list = new ArrayList<>();
preTree(root,list);//前序遍历二叉树
int size = list.size();//链表的长度
for(int i=1;i<size;i++){
TreeNode pre = list.get(i-1),curr = list.get(i);
pre.left = null;
pre.right = curr;
}
}
//二叉树的递归先序遍历
public void preTree(TreeNode root,List<TreeNode> list){
if(root!=null){
list.add(root);
preTree(root.left,list);
preTree(root.right,list);
}
}
}

三、总结

树这块的题目基本都是有套路可寻的,所以大家在平时多加练习的同时,一定要熟记相关的套路,思路找好,模板一套,齐活!

力扣(LeetCode)刷题第144和114题:二叉树的遍历和相关操作!_数据结构_03


记录时间:2020年12月22日