IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【算法之LeetCode系列(6)】—— 二叉树的遍历 -> 正文阅读

[数据结构与算法]【算法之LeetCode系列(6)】—— 二叉树的遍历

1.二叉树的前序遍历(easy)

前序遍历就是头结点永远第一访问,接着是头结点的左孩子节点,右孩子节点;后序遍历就是左、右、头结点;中序遍历就是左、头结点、右;

所以只要一道题你搞懂了,三道题就是一道题

//这里是官方给出的js中二叉树的构造函数(只写一遍哈)
/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
var preorderTraversal = function(root) {
    let res = [];
    let helper = function(root){
        if(root === null) return;//如果是叶子节点,直接返回
        res.push(root.val);//1.将根节点压入
        helper(root.left);//2.递归遍历左子树,目的——>压入根节点的左子树的头结点
        helper(root.right);//3.递归遍历右子树,目的——>压入根节点的右子树的头结点
    }
    helper(root);
    return res;
};

2.二叉树的中序遍历(easy)

var preorderTraversal = function(root) {
    let res = [];
    let helper = function(root){
        if(root === null) return;//如果是叶子节点,直接返回
        helper(root.left);//1.递归遍历左子树
        res.push(root.val);//2.将根节点压入
        helper(root.right);//3.递归遍历右子树
    }
    helper(root);
    return res;
};

3.二叉树的后序遍历(easy)

var preorderTraversal = function(root) {
    let res = [];
    let helper = function(root){
        if(root === null) return;//如果是叶子节点,直接返回
        helper(root.left);//1.递归遍历左子树
        helper(root.right);//2.递归遍历右子树
        res.push(root.val);//3.将根节点压入
    }
    helper(root);
    return res;
};

4.二叉树的层序遍历(medium)

先给一下力扣官方的题目描述吧 ↓↓↓↓↓
在这里插入图片描述

层序遍历就是按照二叉树的结构,先遍历第一层(根节点)再遍历第二层,接着第三层……(还是看图吧,亲自手绘)

以下是我的图解
在这里插入图片描述

即结果输出要求,首先是第一层从左到右的节点,接着是第二层,第三层……,那这样改怎么做呢,显然,你用之前的递归是无法完成的,因为你递归是向深处遍历,纵向延伸,无法横向移动!

我们需要借助一个数据结构,队列,队列是先进先出表,你想啊,你每次遍历,先把节点压入队列中,只要队列中有东西,你就先遍历队列里面的,没有了我再接着遍历后面的,把后面一层的压入队列里面去,一直循环到没有节点为之,看代码上的详细注释

1. 层序遍历 I
var levelOrder = function(root) {
    let res= [];
    //定义一个队列,根据层次顺序保存节点
    let queue = [root];
    if(root === null) return res;
    while(queue.length > 0){
    	//每次从队列中弹出一个节点,并放到res中去
        let node = queue.shift();
        res.push(node.val);
        //检查弹出的节点,有没有子孩子,有就加入到队列中,这样就把下一层的节点顺序也安排的明明白白的
        if(node.left !== null) queue.push(node.left);
        if(node.right !== null) queue.push(node.right);
    }
    return res;
};

看完注释,如果还是不懂,来看看我的图趴

在这里插入图片描述

2. 层序遍历 I I(easy)(搞不懂为什么这个是easy,是因为变式I做出来了吗)

看一下官方题目描述 ↓↓↓↓↓

在这里插入图片描述

var levelOrder = function(root) {
    let res = [];//存放最终的遍历结果
    //定义一个队列,js中可以使用数组(shift和push方法)模仿一个队列
    let queue = [];
    //首先第一层,先把根节点放入队列,注意,这时候队列里面已经有东西了
    if(root !== null) queue.push(root);
   	//遍历队列里面的节点
    while(queue.length > 0){//只要队列的长度大于0,就一直循环遍历
    //注意,这里需要定义这个队列的长度n,不然队列的长度就是动态变化了哦
        let n = queue.length;
        //定义层级,即level是保存每一层的节点
        let level = [];
        //n是当前层的最大节点数量
        for(let i = 0;i < n;i ++){
        	//从队列头中取出一个节点
            let node = queue.shift();
            //将取出的节点的值压入当前层level
            level.push(node.val);
            //看看取出的这个节点有没有左右子孩子,有就压入到队列里面去
            //所以上面必须有一个n,每一层数量应该是确定好的,而下一层的节点数量也会在这一层遍历完之后确定好
            if(node.left) queue.push(node.left);
            if(node.right) queue.push(node.right);
        }
        //将当前层的节点作为一个整体压入结果中
        res.push(level);
    }
    return res;
};
3. 层序遍历 I I I(锯齿形层序遍历)

官方题目描述 ↓↓↓↓↓

在这里插入图片描述

其实变式三,就是变式二的一点小改动,每次压入当前层节点的位置不一样而已,奇数从队列的尾插入,偶数从队列头插入,而队列是在头部先进先出(一般),所以,每次出队列的顺序就会按奇偶而不同了

var levelOrder = function(root) {
    let count = 0;
    let ans = [];
    let res = [];
    let queue = [root];
    if(root ===  null) return res;
    while(queue.length > 0){
        count ++;//控制层数,遍历完一层,层数加一
        level = [];
        let len = queue.length;
        for(let i = 0;i < len;i ++){
            let node = queue.shift();
            //偶数层,从头部依次加入队列,这样,出队列就是最后一个进的先出队列
            //牢记unshift()方法是从数组第一个元素之前开始添加元素,即新添加的元素是数组的第一个元素
            if(count % 2 === 0) level.unshift(node.val);
            //奇数层,从队列尾部压入,这样,出队列就是正常顺序,从左向右
            else level.push(node.val);
            if(node.left !== null) queue.push(node.left);
            if(node.right !== null) queue.push(node.right);
        }
        res.push(level);
    }
    return res;
};

ok,今天就到这里了,感谢浏览,码字不易,不介意的话,给个一键三连再走呗 ヾ(?°?°?)ノ゙

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-27 13:04:40  更:2021-10-27 13:04:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:30:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码