52 # 二叉树的前中后遍历

news2024/10/7 11:25:59

二叉树的遍历

线性数据结构遍历比较简单,可以采用正序遍历、逆序遍历。

遍历树的目的一般是修改树,比如修改树的节点,采用访问者模式

前序遍历

前序遍历(preorder traversal):先访问根节点,前序遍历左子树,前序遍历右子树;遍历 dom 树可以使用

在这里插入图片描述

perorderTraversal(visitor) {
    if (visitor == null) return;
    const traversal = (node) => {
        if (node === null) return;
        visitor.visit(node);
        traversal(node.left);
        traversal(node.right);
    };
    traversal(this.root);
}

在这里插入图片描述

中序遍历

中序遍历(inorder traversal):中序遍历左子树,根节点,中序遍历右子树;可以顺序打印数据

在这里插入图片描述

inorderTraversal(visitor) {
    if (visitor == null) return;
    const traversal = (node) => {
        if (node === null) return;
        traversal(node.left);
        visitor.visit(node);
        traversal(node.right);
    };
    traversal(this.root);
}

在这里插入图片描述

后序遍历

后序遍历(postorder traversal):后序遍历左子树,后续遍历右子树,根节点;遍历子节点可使用后序遍历

在这里插入图片描述

postorderTraversal(visitor) {
    if (visitor == null) return;
    const traversal = (node) => {
        if (node === null) return;
        traversal(node.left);
        traversal(node.right);
        visitor.visit(node);
    };
    traversal(this.root);
}

在这里插入图片描述

层序遍历

层序遍历(level order traversal):从上到下,从左到右依次访问每一个节点

在这里插入图片描述

完整代码

实现如下:

// 节点
class Node {
    constructor(element, parent) {
        this.element = element; // 存的数据
        this.parent = parent; // 父节点
        this.left = null; // 左子树
        this.right = null; // 右子树
    }
}

class BST {
    constructor(compare) {
        this.root = null;
        this.size = 0; // 节点个数
        this.compare = compare || this.compare;
    }
    compare(e1, e2) {
        return e1 - e2;
    }
    // 添加节点
    add(element) {
        // 如果根元素不存在
        if (this.root === null) {
            this.root = new Node(element, null);
            this.size++;
            return;
        } else {
            // 如果根元素存在,那么增加的就不是根节点,需要找到 parent
            let currentNode = this.root;
            // 当前比较的结果
            let compare = 0;
            // 先找到需要对比的 parent(当前父节点)
            let parent = null;
            while (currentNode) {
                parent = currentNode;
                compare = this.compare(element, currentNode.element);
                // 如果大于 0 找右树,小于 0 找左树
                if (compare > 0) {
                    currentNode = currentNode.right;
                } else if (compare < 0) {
                    currentNode = currentNode.left;
                } else {
                    // 如果比较后结果一样,由自己决定是否需要覆盖
                    currentNode.element = element; // 覆盖
                    return;
                }
            }
            // 找到了 parent,生成新节点
            let newNode = new Node(element, parent);
            if (compare > 0) {
                parent.right = newNode;
            } else {
                parent.left = newNode;
            }
        }
    }
    // 先序遍历
    perorderTraversal(visitor) {
        if (visitor == null) return;
        const traversal = (node) => {
            if (node === null) return;
            visitor.visit(node);
            traversal(node.left);
            traversal(node.right);
        };
        traversal(this.root);
    }
    // 中序遍历
    inorderTraversal(visitor) {
        if (visitor == null) return;
        const traversal = (node) => {
            if (node === null) return;
            traversal(node.left);
            visitor.visit(node);
            traversal(node.right);
        };
        traversal(this.root);
    }
    // 后序遍历
    postorderTraversal(visitor) {
        if (visitor == null) return;
        const traversal = (node) => {
            if (node === null) return;
            traversal(node.left);
            traversal(node.right);
            visitor.visit(node);
        };
        traversal(this.root);
    }
}

let bst = new BST();

let arr = [10, 8, 19, 6, 15, 22, 20];

arr.forEach((element) => {
    bst.add(element);
});

// 遍历树的目的一般是修改树,比如修改树的节点,采用访问者模式
console.log(
    bst.perorderTraversal({
        visit(node) {
            console.log("visitor.visit---->", node.element);
        },
    })
);
console.log(
    bst.inorderTraversal({
        visit(node) {
            console.log("visitor.visit---->", node.element);
        },
    })
);
console.log(
    bst.postorderTraversal({
        visit(node) {
            console.log("visitor.visit---->", node.element);
        },
    })
);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/742524.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Go语言struct要使用 tags的原因解析

这篇文章主要介绍了为什么 Go 语言 struct 要使用 tags,在本文中&#xff0c;我们将探讨为什么 Go 语言中需要使用 struct tags&#xff0c;以及 struct tags 的使用场景和优势&#xff0c;需要的朋友可以参考下 在 Go 语言中&#xff0c;struct 是一种常见的数据类型&#xf…

由于找不到vcomp100.dll,无法继续执行代码,解决方法

为什么会由于找不到vcomp100.dll,无法继续执行代码问题呢&#xff1f; 文件被误删除&#xff1a;有时候&#xff0c;在进行系统清理或卸载应用程序时&#xff0c;可能会不小心删除了vcomp100.dll文件。如果某个程序依赖于该文件&#xff0c;并且文件被删除&#xff0c;那么该程…

ESP32开发:IDFV4.4配置LVGL8.3

配置LVGL8.3源码 LVGL GITHUB代码仓库如下&#xff1a;https://github.com/lvgl/lvgl/tree/release/v8.3 官方已经在ESP32上移植好的代码demo&#xff0c;目前最新版是LVGL 7.9&#xff1a;https://github.com/lvgl/lv_port_esp32 我们可以将LVGL官方配置好的ESP32 LVGL仓库下…

超详细的学习笔记:CSS盒子模型(附代码示例)

目录 一、CSS三大特性 1、继承性 2、层叠性 3、优先级 4、权重叠加的计算 二、PxCook的基本使用 三、盒子模型 1、盒子模型的介绍 2、内容的宽度和高度 3、边框 (border) 1、连写形式 2、单方向设置 3、单个属性 8、内边距&#xff08;padding&#xff09;和外边…

arm学习stm32之spi总线数码管倒计时

由于时间没有用时间计时器操作&#xff0c;有些误差&#xff0c;后续有空会翻新计时器版本 main.c #include "spi.h" extern void printf(const char *fmt, ...); void delay_ms(int ms) {int i,j;for(i 0; i < ms;i)for (j 0; j < 1800; j); } int num[10…

钉钉提示 redirect_url的域名不在appid的安全域名内

钉钉提示 redirect_url的域名不在appid的安全域名内 1、需要在《钉钉开放平台》- 开发者后台设置《钉钉扫码登陆功能》 2、如果钉钉界面没有钉钉扫码登陆功能-》点击浏览器右下角-》《返回旧版》 3、备注&#xff1a;当前访问的IP地址跟钉钉扫码登陆功能填写的IP地址需保持一致…

代码审计工具Fortify基本使用

最近接触到一款代码审计的工具 — Fortify SCA and Applications 22.2.0&#xff0c;现就其基本使用做一简单介绍&#xff01; Fortify是一个应用安全测试软件&#xff0c;是Micro Focus旗下AST&#xff08;应用程序安全测试&#xff09;产品。 Fortify能够提供静态和动态应用…

Acwing 853.有边数限制的最短路

Acwing 853.有边数限制的最短路 链接:853. 有边数限制的最短路 - AcWing题库 /* 题解:bellman_ford算法 可以算是一种暴力的算法了 他可以解决有复权边的单源最短路径 也可以解决图是否存在负环的问题 还可以求出 不超过k条边的最短路径问题 但是效率低下 时间复杂度为o(nk)n…

超有趣的linux命令2

超有趣的linux命令2 此次实验命令均在Ubuntu16.04版本上测试 注意有些命令需要在图形化界面才能显示效果 温馨提示&#xff1a;可能有人是第一次接触Ubuntu&#xff0c;所以下面详细写了如何配置源和网络&#xff0c;以及安装命令的方式 1. 首先配置软件源 以命令行方式配置…

Comate代码助手推出,现场生成了贪吃蛇游戏,我们距离AI自动编程还有多远?

Comate代码助手推出&#xff0c;现场生成了贪吃蛇游戏&#xff0c;我们距离AI自动编程还有多远&#xff1f; 百度智能云推出“Comate”代码助手&#xff0c;并正式开放邀测&#xff0c;不算很意外。 毕竟让AI写代码&#xff0c;跑一跑贪吃蛇&#xff0c;算是传统艺能。 不过你…

MongoDB 简介及安装(windows环境下)

一、MongoDB 简介 1、MongoDB 是什么 MongoDB 是一个开源的、基于分布式的、面向文档存储的非关系型数据库。是非关系型数据库当中功能最丰富、最像关系数据库的。 MongoDB 将数据存储为一个文档&#xff0c;数据结构由键值(key>value)对组成。MongoDB 文档类似于 JSON 对…

API全场景零码测试机器人——ATGen带来“超自动化”测试模式

HDC期间可参与新手入驻华为云Testplan抽奖活动&#xff0c;活动链接在文末 众所周知&#xff0c;软件服务及组件之间的交互主要依赖大量的API接口。以华为云300多个商用云服务为例&#xff0c;平均每个服务含500接口&#xff0c;接口总数高达10万&#xff0c;接口调用上下文业务…

[GWCTF 2019]babyvm 题解

虚拟机 这是一个虚拟机的题目 上图是虚拟机的执行流程&#xff0c;Dispatcher(分发器)读取Opcode&#xff08;虚拟机操作码&#xff09; 然后根据操作码进行跳转执行 所以做这道虚拟机的题&#xff0c;我们就要找到操作码 并且明白操作码对应的含义 然后对操作码进行一句一…

MySQL整合篇(SQL语句执行流程-->索引篇-->事务篇-->锁篇)

MySQL 基础篇 1.1 执行一条SQL语句会发生什么 1. MySQL架构一共分为两层 server 和 存储引擎层&#xff08;一般为Innodb引擎&#xff09; 主要执行流程都在server层&#xff1a;连接器&#xff0c;查询缓存&#xff0c;解析SQL&#xff08;解析器&#xff09;&#xff0c;执行…

MySQL存储函数和存储过程习题

创建表并插入数据 字段名 数据类型 主键 外键 非空 唯一 自增id INT 是 否 是 是 否name VARCHAR(50) 否 否 是 否 否glass VARCHAR(50) 否 否 是 否 否sch 表内容id name glass1 xiaommg glass 12 xiaojun glass 21、创建一个可以统计…

零代码编程:用ChatGPT批量识别图片PDF中的文字

有些PDF页面是图片格式&#xff0c;要怎么批量把图片中的文字识别出来&#xff1f;借助ChatGPT可以轻松完成这个任务。 首先要安装一些相关的软件和Python库。 安装tesseract-ocr&#xff08;OCR&#xff09;软件&#xff0c;最新版的是tesseract-ocr-w64-setup-v5.3.0.20221…

BP神经网络数据分类——语音特征信号分类(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 BP神经网络是一种常见的人工神经网络&#xff0c;用于数据分类和回归等任务。在语音特征信号分类中&#xff0c;BP神经网络可…

ANSI转义码sehll演示脚本

ANSI转义码是我在修改文字颜色的时候了解的&#xff0c;以下是我翻译的一个shell小程序的画面 原文在此 他使用c写的&#xff0c;我调整了一下&#xff0c;用shell改写了一个 这是上传的脚本文件&#xff0c;设置的是免费的&#xff0c;可以下载看看玩玩 (3条消息) 【免费】A…

Android Java代码与JNI交互基础数据类型转换(三)

🔥 Android Studio 版本 🔥 🔥 基础类型数据的转换 🔥 定义传递基础数据类型到JNI的函数 package com.cmake.ndk1.jni;public class JNIBasicType{static{System.loadLibrary("native-lib");}public native int callNativeInt(int num);public native byte …

javascript-正则表达式匹配出URL地址,批量添加a标签

一开始接到这个需求觉得简单&#xff0c;结果越搞越复杂&#xff0c;反复了很多次&#xff0c;没有特别好的解决方案 最近接到一个需求&#xff0c;客服输入框需要将发送出去的消息中含有url地址匹配出来添加上a标签&#xff0c;但是由于输入框是富文本&#xff0c;所以输入框内…