【JS】数据结构之树结构

news2024/10/6 10:37:06

文章目录

    • 树结构
    • 二叉树
    • 二叉搜索树
    • 平衡树(AVL树)
    • 红黑树

回顾其他数据结构(每种数据结构都有自己特定的应用场景):

  • 数组:通过下标查询很快,插入和删除数据的时候,效率会很低,需要大量元素的位移。
  • 链表:插入和删除效率很高,查找效率低,需要从头开始依次访问链表中每个数据项,直到找到
  • 哈希表:插入、删除、查询效率都很高,但是空间利用率不高,抵触使用的是数组,某些单元没有被利于到。

树结构

树(Tree)是n(n>0)个节点的有限集,n=0,称为空树
在这里插入图片描述

  • 从逻辑上看,树具有以下特定:
1. 任何非空树中有且仅有一个节点是没有前驱节点的,这个节点就是根节点
2. 除根节点之外,其余的节点有且仅有一个与之相连的前驱节点
3. 包括根节点在内,每个节点可以有多个直接相连的后继节点
4. 树形结构是一种具有递归特性的数据结构(任何一颗树又满足树的概念)
5. 树形结构种的数据元素之间存在的关系是:一对多、或者多对一的关系
  • 树的术语:
1. 节点的度: 节点所拥有子树的个数
2. 树的度: 树中节点度的最大值,如上图中:树的度为3
3. 叶子节点: 度为0的节点,如上图中:KLFGHMNJ都是
4. 分支节点: 度不为0的节点(除根节点之外的分支节点统称为:内部节点。根节点又称之为:开始节点)
5. 子节点: 节点的直接后驱。    
6. 父节点: 节点的直接前驱。  
7. 兄弟节点: 具有同一父节点的个节点彼此就是兄弟节点。
8. 路径: 这个节点自上而下的通过每条节点上的每条边
9. 路径长度: 路径所包含的边的个数。
10. 节点层次: 规定根节点的层是 1,其余节点的层数等于父节点的层数加1.
11. 树的深度: 树中所有节点层数的最大值。

树的存储结构:计算机只能是顺序或者是链式的存储,所以树这样的结构是不能够直接存储的,要将其转换为顺序或者链式存储

在这里插入图片描述

  1. 双亲表示法: 双亲表示法采用数组存储普通的树。
    其核心思想:顺序存储每个节点的同时,给各节点附加一个记录其父节点位置的变量,存储的父节点的下标。
    实际操作的时候,就是从上往下,顺序遍历一棵树,并为相应的域赋值。
    优点:可以快速的获取任意节点的父节点位置。
    缺点:如果要获取某个节点的子节点,就得遍历

在这里插入图片描述

  1. 孩子表示法:建立多个指针域,指向它的子节点的地址。
    也就是说,任何一个节点,都掌握它所有的子节点的信息。通过数组+链表的形式来实现。
    顺序表=>数组,从树的根节点开始,使用数组依次存储树的各个节点。
    需要注意的是:它会给各个节点配备一个链表,用于存储各个节点的孩子节点位于数组中的位置。
    如果说,节点没有子节点,则该节点的链表为空链表。

在这里插入图片描述

  1. 孩子兄弟表示法:把普通的树,转成二叉树:从树的根节点开始,依次用链表存储各个节点的孩子节点和兄弟节点。

二叉树

其实所有树的本质都是可以通过二叉树进行模拟出来。

在这里插入图片描述

  • 如果树中每个节点最多只能有2个子节点,这样的树我们称之为二叉树。
  • 二叉树可以为空,也就是没有节点,空二叉树。
  • 若不为空,则它是由根节点和称为其左子树TL和右子树TR的两个不相交的二叉树组成。

二叉树特点:

1. 每个节点最多有2颗子树,不存在度大于2的节点
2. 左子树和右子树是有序的,次序不能任意颠倒
3. 即使树中某个节点只有一颗子树,也要区分他是左子树还是右子树。

二叉树性质:

1. 在二叉树中,第 i 层是最多有 2^i-1 次节点(i>=1)。第一层就是:2^1-1 = 1
2. 在二叉树中,如果深度为 k,那么最多有 2^k-1 个节点

二叉树形态:

1. 空树
2. 只有一个根节点
3. 只有一个左子节点
4. 只有一个右子节点
5. 两个子节点都有
  • 满二叉树:在一颗二叉树中,如果所有的分支节点度存在左子树和右子树,并且所有的叶子都在同一层上,这样的二叉树就是满二叉树。
  • 满二叉树叶子只能出现最下一层,出现在其他层,不可能达成平衡,非叶子节点的度一定是2.
  • 满二叉树一定是完全二叉树,完全二叉树不一定是满二叉树。
    在这里插入图片描述
  • 完全二叉树:除最后一层外,每一层的节点数均达到最大值,最后一层指缺失右边的若干节点。
  • 把右边缺失的节点补齐,那它就是一个满二叉树。
    在这里插入图片描述
  • 斜树:所有的节点都只有左子树或右子树

在这里插入图片描述

二叉搜索树

二叉搜索树(BST:binary search tree),又称二叉查找树、二叉排序树

二叉树对节点是没有任何限制的,而二叉搜索树其实就是普通的二叉树上加了一些限制:

1. 非空左子树的所有的键值都 小于 其根节点的键值
2. 非空右子树的所有的键值都 大于 其根节点的键值
3. 左右子树本身也都是二叉树

二叉搜索树的遍历指:不重复的访问二叉树中所有的节点

先序遍历:1. 访问根节点 2. 先序遍历其左子树 3. 先序遍历其右子树
中序遍历:先递归遍历其左子树,从最后一个左子树开始存入数组,然后回溯遍历双亲结点,再是右子树同理。
后序遍历:1. 后序遍历其左子树 2. 后序遍历其右子树 3. 访问根节点
  • js 实现一个简单的二叉搜索树
// 节点
class Node {
	constructor(value) {
		this.value = value;
		this.left = null;
		this.right = null;
	}
}

// 二叉搜索树
class BinarySearchTree {
	constructor() {
		// 根节点
		this.root = null;
	}
	// 插入值
	insert(value) {
		let newNode = new Node(value);
		// 如果是空树,这个就是根节点
		if(this.root === null){
			this.root = newNode;
		}else{
			this.insertNode(this.root,newNode);
		}
	}
	// 插入值的比较
	insertNode(node, newNode){
		// 右边:大值
		if(newNode.value > node.value){
			if(node.right === null){
				node.right = newNode;
			}else {
				this.insertNode(node.right, newNode);
			}
		}else if(newNode.value < node.value){ // 左边:小值
			if(node.left === null){
				node.left = newNode;
			}else{
				this.insertNode(node.left,newNode);
			}
		}
	}
	// 先序遍历
	preOrderTraversal(cb) {
		this.preOrederTraversalNode(this.root,cb);
	}
	preOrederTraversalNode(node,cb){
		// 空节点直接返回
		if(node === null) return;
		// 打印
		cb(node.value);
		// 遍历所有的左子树
		this.preOrederTraversalNode(node.left,cb);
		// 遍历所有的右子树
		this.preOrederTraversalNode(node.right,cb);
	}
	// 中序遍历
	inOrderTraversal(cb) {
		this.inOrderTraversalNode(this.root,cb);
	}
	inOrderTraversalNode(node,cb){
		if(node === null) return;
		this.inOrderTraversalNode(node.left,cb);
		cb(node.value);
		this.inOrderTraversalNode(node.right,cb);
	}
	// 后序遍历
	postOrderTraversal(cb) {
		this.postOrderTraversalNode(this.root,cb);
	}
	postOrderTraversalNode(node,cb){
		if(node === null) return;
		this.postOrderTraversalNode(node.left,cb);
		this.postOrderTraversalNode(node.right,cb);
		cb(node.value);
	}
	// 最小值
	min(){
		let node = this.root;
		// 找到左边的节点就是最小的值
		while(node.left !== null){
			node = node.left;
		}
		return node.value;
	}
	// 最大值
	max(){
		let node = this.root;
		// 找到左边的节点就是最小的值
		while(node.right !== null){
			node = node.right;
		}
		return node.value;
	}
	// 寻找特定值
	search(val){
		// 获取根节点
		let node = this.root;
		// 通过判断node节点的值和传入val大小
		while(node!==null){
			if(node.value > val){
				node = node.left;
			}else if(node.value < val){
				node = node.right;
			}else {
				return true;
			}
		}
	}
}

const bst = new BinarySearchTree();
bst.insert(11);
bst.insert(7);
bst.insert(15);
bst.insert(5);
bst.insert(3);
bst.insert(9);
// 二叉搜索树结构
console.log(bst);
// 先序遍历
const preArr = [];
const preCb = (val)=>{
	preArr.push(val);
}
bst.preOrderTraversal(preCb);
console.log(preArr);
// 中序遍历
const inArr = [];
const inCb = (val)=>{
	inArr.push(val);
}
bst.inOrderTraversal(inCb);
console.log(inArr);
// 后序遍历
const postArr = [];
const postCb = (val)=>{
	postArr.push(val);
}
bst.postOrderTraversal(postCb);
console.log(postArr);
// 最值
console.log(bst.min());
console.log(bst.max());
// 寻找特定值
console.log(bst.search(9));
  • 运行结果:

在这里插入图片描述
二叉搜索树的优点:可以快速的找到给定的关键字的数据项,并且可以快速的插入和删除
二叉搜索树的缺点:具有局限性,同样的数据,可以对应不同的二叉搜索树、
比较好的二叉搜索树的结构:左右分布均匀,但是我们插入连续的数据的时候,会导致数据分布不均匀、
我们把这种分布不均匀的树称之为:非平衡树

平衡树(AVL树)

为了能以较快的时间O(logN)来操作一棵树,我们需要保证树总是平衡的

  • 至少大部分是平衡的,那么时间复杂度也是接近O(logN)
  • 也就是说树中每个节点左边的子孙节点的个数,应该尽可能的等于每个节点右边的子孙节点的个数。
  • AVL树是最早的一种平衡树,不过现在平衡树的应用基本都是红黑树。
  • 平衡树 又被称之为 二叉平衡树平衡二叉树平衡二叉搜索树等。
1. 除了规定左节点小于根节点,右节点大于根节点以外。
2. 还规定了左子树和右子树的高度相差不能超过 1
  • 平衡因子:左子树的高度减去其右子树的高度
  • 所以平衡二叉树中,各个节点的平衡因子的绝对值小于等于1(-1,0,1)。
  • 就可以满足我们的二叉平衡树条件,平衡二叉树是一颗二叉搜索树,只不过比较矮而已。
    在这里插入图片描述

如果平衡因子的绝对值超过1,那么就称之为失衡,我们插入数据的时候,节点需要随时添加、随时删除,这样就会导致平衡二叉树出现失衡。

控制平衡因子:要把平衡因子控制在绝对值不大于1的范围内(平衡调整),在平衡二叉树中,使用旋转操作来达到平衡。

红黑树

AVL树相对于红黑树,它的插入/删除操作效率都不高,所以整体效率不如红黑树。
红黑树(R-B tree)是一种自平衡的二叉平衡搜索树,以前叫做平衡二叉B树

  • 红黑树相比AVL树,新增了一些特性,正是这5个特性保证了红黑树的平衡性:
1. 节点是红色或者黑色(好比节点上有一个color属性在控制)
2. 根节点是黑色
3. 叶子节点都是黑色的空节点(null节点)
4. 每个红色节点的两个子节点都是黑色,不能有 2 个红色节点直接相连。
5. 从任意节点出发,到其每个叶子节点的路径中包含相同数据的黑色节点。
(是为了保证从根节点到叶子节点的最长路径不大于最短路径的 2 倍)

在这里插入图片描述

  • 红黑树插入数据的时候,会先去遍历数据应该插入到哪个位置,插入的节点一定是红色的。
1. 因为如果插入的节点为红色的时候,有可能插入的是一次不违法红黑树任何规则的节点

2. 而插入黑色节点,必然会导致右一条路径上多了个黑色节点,这种比较难调整

3. 红色节点虽然可能导致出现红红相连的情况,但是这种情况可以通过颜色调换和旋转来调整
  • 比如:要插入一个129的数值到红黑树里面:

在这里插入图片描述
在这里插入图片描述

  • 但是这种违背了红黑树的特性,经过变色调整后,让它符合5个特性:

  • 红黑树的平衡调整有两种方式:变色旋转(左旋转和右旋转)
    在这里插入图片描述

  • 插入的129节点下面还要添加2个黑色的null节点,这时候就符合了红黑树的特性了

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

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

相关文章

新品上线 | 企企通推出达人管理系统,助力达人营销提效增速

01、直播市场发展迅速 企企通达人管理系统应运而生 近年来&#xff0c;直播凭借其即时性、互动性、多样化的优势&#xff0c;迅速在互联网占据一席之地&#xff0c;“直播”模式不断扩展&#xff0c;直播电商应运而生。 在技术发展与市场需求双重驱动下&#xff0c;中国直播市…

day04 springmvc

day04 springmvc 第一章 SpringMVC运行原理 第一节 启动过程 1. Servlet 生命周期回顾 生命周期环节调用的方法时机次数创建对象无参构造器默认&#xff1a;第一次请求 修改&#xff1a;Web应用启动时一次初始化init(ServletConfig servletConfig)创建对象后一次处理请求se…

嵌入式Linux系统中ARM汇编语言的使用方法

大家好&#xff0c;今天主要大家聊一聊&#xff0c;如何在ARM中使用汇编语言的方法。 目录 第一&#xff1a;汇编基础简介 第二&#xff1a;处理器内部数据传输指令 第三&#xff1a;存储器访问指令 第一&#xff1a;汇编基础简介 我们在学习嵌入式Linux开发的时候是绝…

【用户画像】Redis_Jedis测试、将人群包存放到Redis中、挖掘类标签处理过程、决策树、用SparkMLLib实现决策树

文章目录一 Redis_Jedis_测试1 Jedis所需要的jar包2 连接Redis注意事项3 测试相关数据类型&#xff08;0&#xff09;测试连接&#xff08;1&#xff09;Key&#xff08;2&#xff09;String&#xff08;3&#xff09;List&#xff08;4&#xff09;set&#xff08;5&#xff0…

shiro-第一篇-基本介绍及使用

shiro 概述 shior的话&#xff0c;在第一次听说的时候单纯的任务它就是一个安全框架&#xff0c;可以对访问接口的用户进行验证等工作&#xff0c;类似拦截器或过滤器的东西&#xff0c;但是在学习后&#xff0c;发现远远不止这些&#xff0c;它的灵活性和易用性让我震惊&…

408 | 【计网】第二章 物理层 回顾

自用冲刺笔记整理。 部分图片来自王道。 加油ヾ(◍∇◍)ノ゙ (一)通信基础 1.信道、信号、带宽、码元、波特、速率/数据率、信源与信宿等基本概念 单向通信、半双工通信(双方都可接发,不能同时)、全双工通信码元:用一个固定时长(码元宽度)的信号波形表示一位k进制数字。 …

高项 风险管理论文

六个过程&#xff1a; 1&#xff0c;规划风险管理&#xff1a;决定如何进行规划和实施项目风险管理活动。 2&#xff0c;识别风险&#xff1a;判断哪些风险会影响项目&#xff0c;并以书面形式记录其特点。 3&#xff0c;实施定性风险分析&#xff1a;对风险概率和影响进行评…

通信原理学习笔记5-2:数字调制——连续相位和恒包络问题(非线性功放、连续相位CP FSK信号、最小频移键控MSK、GMSK)

为了最大程度利用非线性功放&#xff0c;需要降低信号PAPR&#xff0c;这要求信号具有恒包络特性信道带宽有限&#xff0c;需要降低信号带外泄露&#xff08;进而传输失真小&#xff09;&#xff0c;要求信号具有连续相位特性&#xff08;从而高频成分少&#xff09; 波形连续…

[附源码]java毕业设计文章管理系统查重PPT

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

让你不在为设计商品详情页而烦恼的工具

不想使用之前的详情页设计模板想更换怎么办&#xff1f;不满意自己用软件设计的详情页模板怎么办&#xff1f;下面跟着小编&#xff0c;教你使用这个在线设计工具乔拓云&#xff0c;在工具内不仅有大量的详情页设计模板&#xff0c;还有海量的详情页免扣设计素材能直接使用&…

[附源码]java毕业设计小区物业管理系统论文

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

springmvc-ssm整合

前言:在座的各位大佬好&#xff0c;最近学习了ssm&#xff0c;然后这是一篇整合ssm的笔记&#xff0c;参考的网上某马视频课的笔记嘿嘿~SSM整合需要掌握↓↓↓↓↓↓↓↓一、SSM整合【重点】1 SSM整合配置问题导入1.1 SSM整合流程1.2 SSM整合配置1.2.1 创建工程&#xff0c;添加…

2022年度中国PCB百强榜单公布

近日&#xff0c;2022慕尼黑华南电子展在深圳圆满举办。电巢直播作为电子工程领域流量前沿、专业度高的在线直播平台&#xff0c;参与了本次展会并搭建了“云观展”平台&#xff0c;对展会进行了全程实时直播。 在这场全国性的“电子企业盛会”中&#xff0c;有1100余家来自不…

你真的了解Spring的依赖查找吗?

1.写在前面 前面的博客我们介绍了Spring的总览&#xff0c;今天我们来了解下Spring的依赖查找的相关的内容&#xff0c;我们会从它的前世今生来带你了解下&#xff0c;以及各种类型的查找的方式&#xff0c;同时介绍对应的相对比较安全的查找的方式。以及会介绍一些比较常见的…

分布式系统设计模式和一致性协议,你用过哪些?

1、布隆过滤器 Bloom过滤器是一种节省空间的概率数据结构&#xff0c;用于测试元素是否为某集合的成员。它用于我们只需要检查元素是否属于对象的场景。 在BigTable&#xff08;和Cassandra&#xff09;中&#xff0c;任何读取操作都必须从组成Tablet的SSTable中读取。如果这些…

用于光波导耦合的倾斜光栅分析

1. 摘要 因其在确定衍射级上的高衍射效率&#xff0c;倾斜光栅广泛用于将光耦合到光波导中。如今&#xff0c;倾斜光栅广泛用于增强现实和混合现实应用中。本示例中将示范如何使用VirtualLab Fusion分析文献中具有特定参数的某些倾斜光栅的几何形状&#xff08;例如倾斜角、填充…

Word控件Spire.Doc 【图像形状】教程(1) ;如何在 Word 中插入图像(C#/VB.NET)

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下&#xff0c;轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具&#xff0c;专注于创建、编辑、转…

使用OpenCV计算两幅图像的协方差

要计算协方差首先要知道协方差的数学原理。 定义 Cov(X,Y) E{ [X-E(X)][Y-E(Y)] }为随机量X与Y的协方差。 其中E(X)为随机变量X的期望(均值)&#xff0c;E(Y)为随机变量Y的期望(均值)。 我们通常用下面的这个公式计算协方差。 Cov(X,Y)E(XY)-E(X)E(Y) 另外&#xff0c;大家…

【苹果家庭群发推送】软件安装最新的Appletweetios.macosimessage是用于发送Apple文本消息

推荐内容IMESSGAE相关 作者推荐内容iMessage苹果推软件 *** 点击即可查看作者要求内容信息作者推荐内容1.家庭推内容 *** 点击即可查看作者要求内容信息作者推荐内容2.相册推 *** 点击即可查看作者要求内容信息作者推荐内容3.日历推 *** 点击即可查看作者要求内容信息作者推荐…

单商户商城系统功能拆解33—营销中心—包邮活动

单商户商城系统&#xff0c;也称为B2C自营电商模式单店商城系统。可以快速帮助个人、机构和企业搭建自己的私域交易线上商城。 单商户商城系统完美契合私域流量变现闭环交易使用。通常拥有丰富的营销玩法&#xff0c;例如拼团&#xff0c;秒杀&#xff0c;砍价&#xff0c;包邮…