大牛深入讲解,建议收藏!二叉树各种遍历方式我都帮你总结啦

     if (root.left != null){
        inorderTraversal(root.left);
    }
    //节点不为空,将节点的值添加进列表中
    list.add(root.val);
    //判断此节点的右节点是否为空,如果不为空则将递归遍历此节点的右子树
    if (root.right != null){
        inorderTraversal(root.right);
    }
    //最后返回列表
    return list;
}

}


*   后续遍历(LeetCode 145)

class Solution {
//声明列表
ArrayList list = new ArrayList<>();
public List postorderTraversal(TreeNode root) {
// 如果根节点为空,则直接返回空列表
if (root == null){
return new ArrayList<>();
}
//判断此节点的左节点是否为空,如果不为空则将递归遍历此节点的左子树
if (root.left != null){
postorderTraversal(root.left);
}
//判断此节点的右节点是否为空,如果不为空则将递归遍历此节点的右子树
if (root.right != null){
postorderTraversal(root.right);
}
//节点不为空,将节点的值添加进列表中
list.add(root.val);
//最后返回列表
return list;
}
}


我们通过观察发现,这代码怎么这么像,是的就是很像,他们唯一的区别就是`list.add(root.val);`代码的位置不一样,这行代码就代表文中的 **遍历(访问)**
下图中为前序遍历(**根**左右)

![](https://upload-images.jianshu.io/upload_images/24195226-86f2674a452f8fe2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


 下图中为中序遍历(左**根**右)

![](https://upload-images.jianshu.io/upload_images/24195226-c2100f0b2760e563.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


下图中为后序遍历(左右**根**)

![](https://upload-images.jianshu.io/upload_images/24195226-a509256842c6f3f8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


## 二叉树非递归遍历

> *   用到栈(FILO 先进后出的特性)
> *   每段代码后,都有栈和其中元素的关系具体过程,建议静下心来慢慢看,有助于理解代码如何运行

*   前序遍历

class Solution {
List list = new ArrayList();
public List preorderTraversal(TreeNode root) {
//如果根节点为空,则直接返回空列表
if(root==null){
return new ArrayList();
}
//声明一个栈
Stack stack = new Stack<>();
//将节点入栈
stack.push(root);
//如果栈不为空
while (!stack.empty()){
//从栈弹出这个节点
TreeNode node = stack.pop();
//添加进列表中
list.add(node.val);
// 如果这个节点的右子节点不为空
if (node.right!=null){
// 将其入栈 因为栈是先进后出,所以先压栈右子节点 后出
stack.push(node.right);
}
// 如果这个节点的左子节点不为空
if (node.left!=null){
// 将其入栈 因为栈是先进后出,所以后压栈左子节点 先出
}
}
//返回列表
return list;
}
}

![](https://upload-images.jianshu.io/upload_images/24195226-17daca543ecb78fe.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


![](https://upload-images.jianshu.io/upload_images/24195226-cab510c23a144af5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


*   中序遍历

class Solution {
public List inorderTraversal(TreeNode root) {
//判断节点是否为空,为空的话直接返回空列表
if (root == null){
return new ArrayList();
}
//声明列表存储结果
List list = new ArrayList();
//声明一个栈
Stack stack = new Stack<>();
//当节点不为空或者栈不为空时
while (root != null || !stack.empty()){
//当节点不为空时
while (root != null){
//将节点压栈
stack.push(root);
//将节点指向其左子节点
root = root.left;
}
//如果栈不为空
if (!stack.empty()){
//将栈里元素弹出来
TreeNode node = stack.pop();
//添加进列表中
list.add(node.val);
//将节点指向其右子节点
root = node.right;
}
}
return list;
}
}


![](https://upload-images.jianshu.io/upload_images/24195226-0c3c44ad935b4ebd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


![](https://upload-images.jianshu.io/upload_images/24195226-5029d7b51fc12ec6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


*   后序遍历

class Solution {
public List postorderTraversal(TreeNode root) {
// 如果根节点为空,则直接返回空列表
if (root == null){
return new ArrayList<>();
}
//声明列表
ArrayList list = new ArrayList<>();
//声明栈A
Stack stackA = new Stack();
//声明栈B
Stack stackB = new Stack();
//将次元素压入栈A
stackA.push(root);
//当栈A不为空时
while (!stackA.empty()){
//取出其中压入的元素
TreeNode node = stackA.pop();
//压入栈B中
stackB.push(node);
//当此节点左子节点不为空时
if (node.left != null){
//压入栈A
stackA.push(node.left);
}
//当此节点右子节点不为空时
if (node.right != null){
//压入栈A
stackA.push(node.right);
}
}
//当栈B不为空时
while (!stackB.empty()){
//取出其元素并且添加至列表中
TreeNode node = stackB.pop();
list.add(node.val);
}
//最后返回列表
return list;
}
}


![](https://upload-images.jianshu.io/upload_images/24195226-22219c751fa541cc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](https://upload-images.jianshu.io/upload_images/24195226-ed02783ebb046cfe.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


## 二叉树层序遍历(BFS)

> *   LeetCode 102 二叉树的层序遍历
> *   用到队列(FIFO 先进先出的特性)代码后有队列和其中元素的关系具体过程,建议静下心来慢慢看,有助于理解代码如何运行

class Solution {
public List<List> levelOrder(TreeNode root) {
if (root == null) {
return new ArrayList<List>();
}
// 声明一个列表存储每一行的数据
List<List> result = new ArrayList<>();
//声明一个队列
LinkedList queue = new LinkedList<>();
//如果根节点不为空,将其入队
queue.offer(root);
//当队列不为空时,代表队列里有数据
while (!queue.isEmpty()) {
//存储每一行的数据line
List line = new ArrayList();
//保存队列中现有数据的个数,这些就是要添加至每一行列表的值
int size = queue.size();
for (int i=0;i<size;i++){
//取出队列的节点 (FIFO 先进先出)
TreeNode node = queue.poll();
line.add(node.val);
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
}
result.add(line);
}
return result;
}
}


![](https://upload-images.jianshu.io/upload_images/24195226-ae71237befb5fcea.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


## leetcode二叉树相关练习

*   我们看到了这里,对二叉树的前序(DFS)、中序、后序、递归/非递归以及层次遍历(BFS)都有了一定的了解(**如果上面的图都消化了的话**)

然后我们趁热打铁来几道leetcode题目试试手!(总体代码和上面只有稍微的改动,因为大致思想是一样的,把上面的内容都消化了的话就很简单啦)

*   leetcode-257 二叉树的所有路径

class Solution {
public List binaryTreePaths(TreeNode root) {
if (root == null){
return new ArrayList<>();
}
ArrayList list = new ArrayList<>();
Stack stack = new Stack();
//这个栈存储路径,与上一个存储节点的栈一样的操作
Stack path = new Stack();
stack.push(root);
path.push(root.val+"");
while (!stack.empty()){
TreeNode node = stack.pop();
String p = path.pop();
//当是叶子节点的时候,此时栈中的路径即为一条完整的路径,可以加入到结果中
if (node.right == null && node.left == null ){
list.add§;
}
//如果右子节点不为空
if (node.right != null){
stack.push(node.right);
//将临时路径继续压栈
path.push(p+"->"+node.right.val);
}
//如果左子节点不为空
if (node.left != null){
stack.push(node.left);
//将临时路径继续压栈
path.push(p+"->"+node.left.val);
}

总结

谈到面试,其实说白了就是刷题刷题刷题,天天作死的刷。。。。。

为了准备这个“金三银四”的春招,狂刷一个月的题,狂补超多的漏洞知识,像这次美团面试问的算法、数据库、Redis、设计模式等这些题目都是我刷到过的

并且我也将自己刷的题全部整理成了PDF或者Word文档(含详细答案解析),有需要的朋友可以戳这里即可免费领取

我的美团offer凉凉了?开发工程师(Java岗)三面结束等通知...

66个Java面试知识点

架构专题(MySQL,Java,Redis,线程,并发,设计模式,Nginx,Linux,框架,微服务等)+大厂面试题详解(百度,阿里,腾讯,华为,迅雷,网易,中兴,北京中软等)

我的美团offer凉凉了?开发工程师(Java岗)三面结束等通知...

算法刷题(PDF)

自己刷的题全部整理成了PDF或者Word文档(含详细答案解析),有需要的朋友可以戳这里即可免费领取**

[外链图片转存中…(img-ulqTSdSp-1628229528402)]

66个Java面试知识点

架构专题(MySQL,Java,Redis,线程,并发,设计模式,Nginx,Linux,框架,微服务等)+大厂面试题详解(百度,阿里,腾讯,华为,迅雷,网易,中兴,北京中软等)

[外链图片转存中…(img-x4YuEC7F-1628229528405)]

算法刷题(PDF)

我的美团offer凉凉了?开发工程师(Java岗)三面结束等通知...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值