当前位置: 首页 > news >正文

数据结构————树

一、深度优先遍历和广度优先遍历

深度优先遍历

从根出发,尽可能深的搜索树的节点

技巧:

  1. 访问根节点
  2. 对根节点的children挨个进行深度优先遍历

广度优先遍历

从根出发,优先访问离根节点最近的节点

技巧:

  1. 新建一个队列,把根节点入队
  2. 把队头出队
  3. 把队头的children挨个入队
  4. 重复2和3步,直到队列为空为止
//树
const tree = {
    val: 'a',
    children: [
        {
            val: 'b',
            children: [
                { val: 'c', children: [] },
                { val: 'd', children: [] },
            ]
        },
        {
            val: 'e',
            children: [
                { val: 'f', children: [] },
                { val: 'g', children: [] },
            ]
        }
    ]
}
//深度优先遍历
const fun1 = (root)=>{
    console.log(root.val);
    root.children.forEach(fun1);
}
fun1(tree)
//广度优先便利
const fun2 = (root) => {
    const arr=[root]
    while (arr.length > 0) {
        var item = arr.shift()
        console.log(item.val);
        item.children.forEach(item => {
            arr.push(item)
        })
    }
}
fun2(tree)

前序、中序、后序遍历

前序遍历(左、右)

在这里插入图片描述

const tree = {
    val: '1',
    left:{
        val:'2',
        left: { val: '4', left: null, right: null },
        right: { val: '5', left: null, right: null },
    },
    right: {
        val: '3',
        left: { val: '6', left: null, right: null },
        right: { val: '7', left: null, right: null },
    }
}

//递归
var preorderTraversal = function (root) {
    let arr=[]
    var fun = (node) => {
        if (node) {
            //先根节点
            arr.push(node.val)
            //遍历左子树
            fun(node.left)
            //遍历右子树
            fun(node.right)
        }
    }
    fun(root)
    return arr
}
console.log(preorderTraversal(tree));//['1', '2', '4', '5', '3', '6', '7']

//非递归
var preorderTraversalTwo=function(root){
    if (!root) return [];
    let arr = []
    //根节点入栈
    let stack = [root]
    while (stack.length) {
        let current = stack.pop()
        arr.push(current.val)
        current.right ? stack.push(current.right) :null
        current.left ? stack.push(current.left):null
    }
    return arr
}
console.log(preorderTraversalTwo(tree));

中序遍历(左、中,右)

在这里插入图片描述

const tree = {
    val: '1',
    left:{
        val:'2',
        left: { val: '4', left: null, right: null },
        right: { val: '5', left: null, right: null },
    },
    right: {
        val: '3',
        left: { val: '6', left: null, right: null },
        right: { val: '7', left: null, right: null },
    }
}

//递归
var inorderTraversal = function (root) {
    let arr=[]
    var fun = (node) => {
        if (node) {
            //遍历左子树
            fun(node.left)
            //根节点
            arr.push(node.val)
            //遍历右子树
            fun(node.right)
        }
    }
    fun(root)
    return arr
}
console.log(inorderTraversal(tree));

//非递归
var inorderTraversalTwo=function(root){
    if (!root) return [];
    let arr = []
    let stack = []
    let o=root
    while (stack.length || o) {
        while (o) {
            stack.push(o)
            o=o.left
        }
        const n = stack.pop();
        arr.push(n.val)
        o=n.right
    }
    return arr
}
console.log(inorderTraversalTwo(tree));//['4', '2', '5','1', '6', '3','7']

后序遍历(左、右、中)

在这里插入图片描述

const tree = {
    val: '1',
    left:{
        val:'2',
        left: { val: '4', left: null, right: null },
        right: { val: '5', left: null, right: null },
    },
    right: {
        val: '3',
        left: { val: '6', left: null, right: null },
        right: { val: '7', left: null, right: null },
    }
}

//递归
var postorderTraversal = function (root) {
    let arr=[]
    var fun = (node) => {
        if (node) {
            //遍历左子树
            fun(node.left)
            //遍历右子树
            fun(node.right)
            //根节点
            arr.push(node.val)
        }
    }
    fun(root)
    return arr
}
console.log(postorderTraversal(tree));['4', '5', '2','6', '7', '3','1']

//非递归
var postorderTraversalTwo=function(root){
    if (!root) return [];
    let arr = []
    //根节点入栈
    let stack = [root]
    while (stack.length) {
        let current = stack.pop()
        arr.unshift(current.val)
        current.left ? stack.push(current.left) : null
        current.right ? stack.push(current.right) : null
    }
    return arr
}
console.log(postorderTraversalTwo(tree));

相关文章:

  • 【操作系统】 第二章 —— 系统调用 中断 异常
  • 移动端测试
  • Cmake、Qt与VS编译VTK(生成QVTK)
  • Java——JDBC(Java DataBase Connectivity)数据库连接技术
  • Express
  • java学习之springcloud之服务调用+服务降级+服务网关篇
  • 常见的设计模式
  • 【我不熟悉的javascript】02. 使用token和refreshToken的管理用户登录状态
  • 备战秋招涵盖二十九大技术栈Java面试最新八股文来袭
  • tensorflow张量运算
  • 论文阅读笔记StyTr2: Image Style Transfer with Transformers
  • mybatis面试题及回答
  • 奔腾电力面试题
  • 【leetcode】905. 按奇偶排序数组 (简单)
  • Java--MybatisPlus入门;与Mybatis区别;简单使用(一)
  • 2017-08-04 前端日报
  • create-react-app项目添加less配置
  • C语言笔记(第一章:C语言编程)
  • Js实现点击查看全文(类似今日头条、知乎日报效果)
  • js数组之filter
  • Laravel5.4 Queues队列学习
  • Laravel核心解读--Facades
  • Python语法速览与机器学习开发环境搭建
  • React Native移动开发实战-3-实现页面间的数据传递
  • Redis 中的布隆过滤器
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • UMLCHINA 首席专家潘加宇鼎力推荐
  • windows下使用nginx调试简介
  • WordPress 获取当前文章下的所有附件/获取指定ID文章的附件(图片、文件、视频)...
  • 老板让我十分钟上手nx-admin
  • 悄悄地说一个bug
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • # 飞书APP集成平台-数字化落地
  • (007)XHTML文档之标题——h1~h6
  • (16)UiBot:智能化软件机器人(以头歌抓取课程数据为例)
  • (2021|NIPS,扩散,无条件分数估计,条件分数估计)无分类器引导扩散
  • (第二周)效能测试
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (正则)提取页面里的img标签
  • (转)linux下的时间函数使用
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • (转)Sublime Text3配置Lua运行环境
  • (转)关于如何学好游戏3D引擎编程的一些经验
  • .libPaths()设置包加载目录
  • .net core 3.0 linux,.NET Core 3.0 的新增功能
  • .net core 依赖注入的基本用发
  • .NET gRPC 和RESTful简单对比
  • .net 简单实现MD5
  • .net 桌面开发 运行一阵子就自动关闭_聊城旋转门家用价格大约是多少,全自动旋转门,期待合作...
  • /bin/rm: 参数列表过长"的解决办法
  • @ 代码随想录算法训练营第8周(C语言)|Day57(动态规划)
  • @ComponentScan比较
  • [Android View] 可绘制形状 (Shape Xml)
  • [BUAA软工]第一次博客作业---阅读《构建之法》
  • [C++打怪升级]--学习总目录