JS简单实现树结构

2023-11-15

本文借鉴于此

一、树的基本概念

1、树: 树是由n(n>0)个有限节点组成的一个具有层次关系的集合,它具有以下的特点:

每个节点有0个或多个结点
没有父节点的节点叫做根节点
每个非根节点有且只有一个父节点
除了根节点外,每个子节点可以分为多个不相交的子树

在这里插入图片描述
2、节点的度: 节点拥有的子树个数,例如图中节点A的度为2,节点H的度为1

3、树的度: 树的最大节点的度,例如图中最大的节点B的度为3,树的度为3

4、叶节点: 度为0的节点,图中K,J,F,L,O,P都是叶节点

5、父节点: 一个含有子节点的节点。图中A节点就是B 和 C的父节点

6、子节点: 一个含有子树的根节点的节点,把子树的根节点叫做该节点的该节点的子节点,图中节点G和节点H为节点C的子节点

7、兄弟节点: 具有相同父节点的节点,节点B和节点C就是兄弟节点

8、祖先节点: 从根到该节点所经分支的所有节点,图中节点A,B,E是节点J的祖先节点

9、子孙节点: 以某节点为根节点的子树中所有节点,图中节点D、E、F、J、K、I是节点B的子孙节点

10、节点层次: 以根开始,根为第一层,根的子节点为第二层…,如果一个节点在第n层,则它的子树的根节点在n+1层

11、深度或高度: 树中节点的最大层次

12、森林: 由n棵互不相交的树的集合,例如图中节点A去掉,以节点B为根的树和以节点C为根的树组成的集合就叫做森林

二、二叉树

1、二叉树的概念

(1)二叉树:是每个节点最多只有两个子树的树结构,这两种子树通常叫做左子树和右子树,具有左右次序,不能颠倒

(2)二叉树的特点:

a、二叉树的第i层至多有2^(i-1)个节点(i>= 1)
b、高度为k的二叉树至多有2^k-1个节点(k>=1)
c、非空二叉树中,叶子结点数为n0,度为2的节点数为n2,则n0 = n2 + 1
d、具有n个节点的完全二叉树的深度为不大于log2n的最大整数

特点 c 推导:

	设n为二叉树的总节点数,n0为二叉树中叶子节点数,n1为二叉树中度为1的节点数,n2为二叉树中度为2的节点数
	可得  n = n0 + n1 + n2
	根据二叉树中的连接线数可再得一个关系  (总线数)n - 1 = n1 + 2n2
	求方程可得   n0 = n2 + 1

2、满二叉树

在一棵二叉树中,所有的分支节点都存在左子树和右子树,并且所有的叶子结点都在同一层上

3、完全二叉树

对于一棵具有n个节点的二叉树按层序编号,如果编号为 i (i <= i <= n)的节点与同样深度的满二叉树中编号为i的结点在二叉树中的位置

完全相同,则这棵二叉树称为完全二叉树

三、二叉搜索树

1、二叉搜索树的性质

(1)若任意节点的左子树不为空,则左子树上所有节点的值都小于它根节点的值
(2)若任意节点的右子树不为空,则右子树上所有节点的值都大于它根节点的值
(3)任意节点的左右子树也分别为二叉搜索树
(4)没有值相等的节点

2、定义节点类和二叉树类

(1)由二叉树的定义,我们可以对节点定义代表存储左子树和右子树的属性

function Node(data) {
    this.data = data
    this.leftChild = null
    this.rightChild = null
}

对于二叉树来说,定义一个根节点的属性

function BinaryTree() {
    this.root = null//根结点
}

例如下图是Node环境输出的二叉树的结构,一个对象嵌套着一个对象
在这里插入图片描述

3、插入节点

由二叉搜索树的性质,可以得到插入的过程:

1、二叉树为空,新节点为根节点
2、二叉树不为空,由根节点开始,新节点的值小于当前节点,往左子树递归,若大于当前节点,往右子树递归,直到为null的时候插入
BinaryTree.prototype.inserNode = function(data) {
    var newNode = new Node(data);  // 构造Node的实例
  
    if (this.root === null) {  // 根节点为空, 新节点为根节点
      this.root = newNode;
    } else {
      insert(this.root, newNode);
    }
};


var insert = function(node, newNode) {
    if (newNode.data < node.data) {
      insertChild(node, 'leftChild', newNode);
    } else {
      insertChild(node, 'rightChild', newNode);
    }
};


var insertChild = function(node, childName, newNode) {
    if (node[childName] === null) {
      node[childName] = newNode;
    } else {
      insert(node[childName], newNode);
    }
};

4、判断空树

判断空树很简单,当root为null的时候,树就是空树,返回true

BinaryTree.prototype.isBinaryTreeEmpty = funciton() {
    if(this.root) {
        return false
    }

    return true
}

5、二叉搜索树的高度

高度是树的最大层次,可以用递归的方式,分别计算左子树的高度和右子树的高度,然后区取他们之间的最大值

var treeDepth = function(node) {
    var i,j;

    if(node === null) {//空树,高度为0
        return 0
    }

    if(node.leftChild) { //计算左子树的高度
        i = treeDepth(node.leftChild)
    } else {
        i = 0
    }

    if(node.rightChild) {
        j = treeDepth(node.rightChild)
    } else {
        j = 0
    }
    return i > j? i+1 : j+1
}

BinaryTree.prototype.binaryTreeDepth = function() {
    return treeDepth(this.root)
}

6、遍历

(1)先序遍历(深度优先遍历):先访问根节点,其次左子树,再右子树

var preOrderTraverseNode = function(node,callback) {
    checkCallback(callback) //检查callback参数是否为函数的方法

    if(node) {
        callback(node)
        preOrderTraverseNode(node.leftChild,callback)
        preOrderTraverseNode(node.rightChild,callback)
    }
}

BinaryTree.prototype.preOrderTraverseNode = function(callback) {
    preOrderTraverseNode(this.root,callback)
}

var checkCallback = function(callback) {
    if(!callback || typeof callback !== 'function') {
        throw ('Callback function error.')
    }
}

(2)中序遍历:先访问左子树,其次是根节点,最后右子树

关于中序遍历有个性质:二叉搜索树中序遍历为递增序列
var inOrderTraverseNode = function(node,callback) {
    checkCallback(callback)

    if(node) {
        inOrderTraverseNode(node.leftChild,callback)
        callback(node)
        inOrderTraverseNode(node.rightChild,callback)
    }
}

BinaryTree.prototype.inOrderTraverseNode = function(callback) {
    inOrderTraverseNode(this.root,callback)
}

(3)后序遍历:先访问左子树,其次是根节点,最后右子树

var postOrderTraverseNode = function(node, callback) {
  checkCallback(callback);

  if (node) {
    postOrderTraverseNode(node.leftChild, callback);
    postOrderTraverseNode(node.rightChild, callback);
    callback(node);
  }
};

BinaryTree.prototype.postOrderTraverse = function(callback) {
  postOrderTraverseNode(this.root, callback);
};

(4)层次遍历(广度优先遍历):层次遍历是指同深度节点从左到右一次遍历,借助队列,从根节点开始,入列,判断队列是否为空,若不为空,队首出列,将队首的左右子树根节点入列,不断循环至队列的元素全部出列

BinaryTree.prototype.levelOrderTraverse = function(callback) {
    var queue = [], e = null;

    checkCallback(callback)

    if(this.root) {
        queue.push(this.root)
    }

    while(queue.length > 0 ) {
        e = queue.shift()
        callback(e)

        if(e.leftChild) {
            queue.push(e.leftChild)
        }

        if(e.rightChild) {
            queue.push(e.rightChild)
        }
    }
} 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JS简单实现树结构 的相关文章

  • 实战: 跨年烟花代码的实现(附源码)

    目录 前言 一 pandas是什么 二 代码结构 1 介绍主html代码 2 js文件介绍 GameCanvas js script js 运行效果 前言 本文章将介绍跨年烟花代码的实现以及源代码 提示 以下是本篇文章正文内容 一 pand
  • 【H5】 svg内text、image、path标签的使用

    H5 svg内text image path标签的使用 text标签 div style width 500px height 500px border 2px solid pink margin 50px auto 0 div
  • 兼容ios不支持的日期格式

    前段时间开发了一个关于订单展示的页面 要求根据时间筛选出离当前时间最近的订单信息进行展示 因为服务器返回的时间格式都是 YYYY MM DD 也没想那么多 直接拿过来就用了 在安卓上排序都很正常 在测试的时候发现苹果手机展示的订单根本就没有
  • JSP通用分页

    通用分页核心思路 将上一次查询请求再发一次 只不过页码变了 实现步骤 1 先查询全部数据 baseDao
  • 看天气WeatherCan V1.0 ---气象数据分析系统web版

    版权声明 本文为CSDN博主 老郭1 的原创文章 遵循CC 4 0 BY SA版权协议 转载请附上原文出处链接及本声明 原文链接 https blog csdn net HZGJF article details 104772394 Wea
  • 第八站:JavaScript的数据类型、运算符、流程控制语句

    第八站 JavaScript的数据类型 运算符 流程控制语句 欢迎来到第八站 JavaScript的数据类型 运算符 流程控制语句 在这一站 我们将深入探索JavaScript中的核心概念 为你揭示这个语言的奇妙之处 准备好继续冒险了吗 让
  • 前端学习——JavaScript原生实现购物车案例

    一 购物车案例 1 1 案例介绍 今天我们来写另外一个购物车案例 说实话对于我来说这个是花了将近三个小时的时间然后才做出来的 里面可能还存在一些我没有发现的问题 但是能完成基本的功能 对于一些基本的需求都是可以完成的 下面照旧是案例实现的g
  • 网页引用Font Awesome图标

    方法一 demo html
  • c语言药房管理系统

    include
  • angular:路径找不到时会跳回主页

    本地起服时 如果输入的路径无法匹配现有规则 则会跳转至主页 带来一定困扰 最好是统一显示或者导航至特定页面 以便debug const routes Routes path component PageNotFoundComponent
  • 通过点击按钮在页面添加图片

    点击添加按钮 在盒子中加入图片 点击图片实现删除图片效果 代码如下
  • WEB交互界面易用性设计和验收的指导性原则

    随着企业intranet和国际internet的迅速发展 越来越多的工作流程 商务交易 教育 培训 会议和讲座 以及个人消费娱乐都被转移到所谓的万维网 World Wide Web 以下简称WEB 上来了 与此相对应的是交互操作的复杂性越来
  • 微信小程序:图片高度设置无效问题

    控制台查看元素 显示其style中多了一个没有设置的高度值 找了很久发现是因为image标签设置了mode widthFix 此时高度会自适应 样式中设置高度无效
  • flex布局详解

    声明 本人的所有博客皆为个人笔记 作为个人知识索引使用 因此在叙述上存在逻辑不通顺 跨度大等问题 希望理解 分享出来仅供大家学习翻阅 若有错误希望指出 感谢 flex基本概念 任何一个容器都可以指定为Flex布局 例如 box displa
  • 【H5】 svg画扇形饼图

    H5 svg画扇形饼图 效果图如下 封装代码如下 代码内有详细注解哦
  • elementui 禁止浏览器自动填充用户名密码

    浏览器这功能在登录的时候挺好用的 但是在注册和管理的时候就很难受了 所以 在普通的input上直接off就行了
  • 移动端适配-01-百分比宽度

    1 图片可以在parent中使用 1 line heigh和text align使水平和竖直居中 2 在img标签中加vertical align middle 2 3 background size 1 两个参数 background s
  • 【HTML】HTML5的拖放你用了吗

    HTML HTML5的拖放你用了吗 引言 github HTML HTML5的拖放你用了吗 内容速递 看了本文您能了解到的知识 在 HTML5 中 拖放是标准的一部分 任何元素都能够拖放 拖放的操作 多用在拖拽排序列表 游戏拼图等 下文中出
  • 测试基础知识

    常见测试分类 按测试阶段划分 单元测试 针对程序源码进行测试 国内是开发自测 集成测试 又称接口测试 针对模块间的访问地址进行测试 系统测试 对整个系统进行测试 包括功能 兼容性 文档等 验收测试 分为内测和公测 按代码可见度划分 黑盒测试
  • 基于html5的国家历史文物网站的设计与实现-计算机毕业设计源码63653

    目 录 摘 要 Abstract 第 1 章

随机推荐

  • Java 线程同步 - 7种方式

    为何要使用同步 java允许多线程并发控制 当多个线程同时操作一个可共享的资源变量时 如数据的增删改查 将会导致数据不准确 相互之间产生冲突 因此加入同步锁以避免在该线程没有完成操作之前 被其他线程的调用 从而保证了该变量的唯一性和准确性
  • 3分钟学习:获取 URL 查询参数值

    在前端开发工作中 利用 URL 进行参数传递是一项十分常见的方法 在页面跳转时 通过 URL 携带某些信息 如状态 id 区分页面来源的字段值等 因此 学习了解如何获取 URL 查询参数值是很重要的 js 代码手撸 利用 JavaScrip
  • 使用sessionStorage新建与本页面一样的Tab页面,并在页间传递参数。

    客户提了个需求 点击某个链接 新建一个Tab页 当前页面内容不变 新的Tab页中控件的值和当前页一致 查阅了相关博客 发现可以用sessionStorage或者localStorage实现 键值对属性的存储 获取 Demo实现思路 页面加载
  • TCP/IP UDP 协议首部及数据进入协议栈封装的过程

    数据的封装 UDP 封装 TCP 封装 IP 封装 检验和算法 当应用程序用TCP传送数据时 数据被传送入协议栈中 然后逐一通过每一层直到被当作一串比特流送入网络 注 UDP数据TCP数据基本一致 唯一不同的是UDP传给IP的信息单元称作U
  • 【详解python中round函数】

    在Python中 round 函数是一个内置函数 用于将一个数字四舍五入为指定的小数位数或整数位数 round 函数有两个参数 第一个参数是要四舍五入的数字 第二个参数 可选 是小数位数或整数位数 表示要保留的小数位数或整数位数 默认为0
  • iOS 审核被拒绝3.2.1 没有金融许可证

    今年金融行业不好做 p2p暴雷好多家 上半年Android应用市场整顿金融类应用 在华为应用市场被误认为p2p应用而下架 经过上诉上传资质证明得而重新上架 各个应用商店平台陆续需要资质证明 最近应用在苹果商店审核被拒绝 同样也是因为金融类资
  • Redirecting to /bin/systemctl stop iptables.service Failed to stop iptables.service: Unit iptables.s

    学习远程访问mysql时 由于centos的防火墙会自动屏蔽很多软件的端口 所以无法连接 于是要关闭防火墙 网上找方法后知道输入 service iptables stop可以关闭防火墙 但是没有成功 因为centos7不能关闭防火墙 所以
  • 这真是冷门又逆天的副业,赚的有点多,分享一下接单心得

    前言 每年春节前后 都会是Python兼职接单的小高潮 这段时间各个行业对爬虫类和数分类的需求会暴增 圈子里很多朋友双休都没闲着 两天赚上万的不在少数 最近发现技术变现 兼职接单问题很多 我总结下来 发现大部分人都有着相同的困惑 听说Pyt
  • CSS鼠标滑过翻转动画图标

    html css鼠标放上去变大效果 效果如下动态图 目录层级 代码如下 html文件 index html li li
  • 图片存在灰白、深黑区域的检测

    import cv2 as cv file path E Python pythonProject 4 1 jpg def blackAndwhite screen file path img cv imread file path row
  • python 解决 pip 时报错 no suchoption: --bulid-dir 的解决办法

    python m pip install pip 20 2 4
  • Struts2 commons-fileupload 在上传2M以上文件出现异常解决方法

    在上传2M以上文件出现异常如下 APPNAME ERROR http 80 3 MultiPartRequest parse 130 org apache commons fileupload FileUploadBase SizeLimi
  • FISCO BCOS 区块链

    FISCO BCOS是由国内企业主导研发 对外开源 安全可控的企业级金融联盟链底层平台 由金链盟开源工作组协作打造 并于2017年正式对外开源 社区以开源链接多方 截止2020年5月 汇聚了超1000家企业及机构 逾万名社区成员参与共建共治
  • 泛型是什么,C++泛型编程又是什么?

    泛型是什么 C 泛型编程又是什么 在计算机程序设计领域 为了避免因数据类型的不同 而被迫重复编写大量相同业务逻辑的代码 人们发展的泛型及泛型编程技术 什么是泛型呢 所以泛型 实质上就是不使用具体数据类型 例如 int double floa
  • 高效率同步4开关Buck-Boost DC/DC控制器TMI5700

    随着户外储能电源应用需求的增加 以及PD大功率车充产品的广泛推广 应对不同输入供电设备 如5V 19V的适配器 以及12V 24V车载充电器 或电池组 4 2V 17 6V 都需要转换成5 20V的PD电压来应对不同负载设备的供电需求 图1
  • 基于R的飞机航线数据可视化(卫星地图)

    基于R的飞机航线数据可视化 卫星地图 数据处理 加载库 加载地图 说明 上一篇是基于行政区划进行可视化 本篇是基于卫星地图进行可视化 上一篇指路 基于R的飞机航线数据可视化 行政区划 数据处理 基础数据的处理与上一篇相同 不做解释 加载库
  • Innodb结构

    从MySQL5 5版本开始默认使用InnoDB作为引擎 它擅长处理事务 具有自动崩满恢复的特性 在日常开发中使用非常广泛 下面是言方的InnoDB引擎美构图 主要分为内存结构和磁盘结构两大部分 内存结构主要包括Buffer Pool Cha
  • 【python】设计一个游戏角色类 属性:角色名、血量、魔法、状态 方法:释放技能 被伤害 要求:设计要合理

    设计一个游戏角色类 a 属性 角色名 血量 魔法 状态 b 方法 释放技能 被伤害 c 要求 设计要合理 import time class Civillian name bp 1100 mp 2000 state def backgrou
  • 实现Tab页之间通信的方式

    5 种方式 localstorage webworker web socket cookie postMessage localstorage 先看效果 test3 gif 代码
  • JS简单实现树结构

    本文借鉴于此 一 树的基本概念 1 树 树是由n n gt 0 个有限节点组成的一个具有层次关系的集合 它具有以下的特点 每个节点有0个或多个结点 没有父节点的节点叫做根节点 每个非根节点有且只有一个父节点 除了根节点外 每个子节点可以分为