javascript数据结构与算法-- 二叉树

javascript数据结构与算法-- 二叉树

  树是计算机科学中经常用到的一种数据结构。树是一种非线性的数据结构,以分成的方式存储数据,树被用来存储具有层级关系的数据,比如文件系统的文件,树还被用来存储有序列表。我们要研究的是二叉树,在二叉树上查找元素非常快,为二叉树添加元素或者删除元素,也是非常快的。

树的基本结构示意图如下:

我们现在最主要的是要来学习二叉树,二叉树是一种特殊的树,它的特征是 子节点个数不超过2个。如下图就是二叉树的基本结构示意图如下:

二叉树是一种特殊的树,相对较少的值保存在左节点上,较大的值保存在右节点中。这一特性使得查找的效率非常高,对于数值型和非数值型的数据,比如单词和字符串都是一样。

下面我们来学习插入节点的操作吧!

1.   二叉树是由节点组成的,所以我们需要定义一个对象node,可以保存数据,也可以保存其他节点的链接(left 和 right),show()方法用来显示保存在节点中的数据。Node代码如下:

复制代码

 function Node(data,left,right) {this.data = data;this.left = left;this.right = right;this.show = show;
}

复制代码

插入节点分析如下:

代码如下:

复制代码

function Node(data,left,right) {this.data = data;this.left = left;this.right = right;this.show = show;
}
function show() {return this.data;
}
function BST() {this.root = null;this.insert = insert;this.inOrder = inOrder;
}
function insert(data) {var n = new Node(data,null,null);if(this.root == null) {this.root = n;}else {var current = this.root;var parent;while(current) {parent = current;if(data <  current.data) {current = current.left;if(current == null) {parent.left = n;break;}}else {current = current.right;if(current == null) {parent.right = n;break;}}}}
}
初始代码如下:
var nums = new BST();
nums.insert(23);
nums.insert(45);
nums.insert(16);
nums.insert(37);
nums.insert(3);
nums.insert(99);
nums.insert(22);

复制代码

示意图如下:

1. 执行insert(23)时候,由于根节点== null 所以 根节点为23.

2. 执行insert(45)的时候,根节点不等于null,因此进入while语句;由于45 > 大于根节点23 所以就进入else语句,当前current的值如下图:

当执行 current = current.right; 这句代码时候,当前current值变为null了,然后进行if判断代码如下:

if(current == null) {parent.right = n;break;}

所以45为根节点的右节点了。跳出循环语句;

3. 执行insert(16)的时候,根节点不等于null,因此进入while语句,由于16 < 小于根节点23,所以就进入if语句,那么当前的current值如下:

当执行到 current = current.left; 的时候,current的值就变为null,所以接着往下执行代码:

if(current == null) {parent.left = n;break;
}

就把当前的节点16插入到根节点的左节点上。

4. 接着执行 insert(37) 的时候,根节点不等于null,因此进入else语句中的while语句,由于37 大于根节点23,所以就进入while语句中的else语句,当前的current值为:

当执行current = current.right;这句代码的时候,那么当前current = 45的那个节点(如上图所示);当再执行下面的代码:

if(current == null) {parent.right = n;break;
}

那么current != null 所以接着进入下一次while循环,执行这句代码后;parent = current;

那么parent = 45的那个节点了,current值如下所示:

接着进入if语句判断,由于当前的根节点是45,所以37 小于根节点 45了,所以就进入if语句代码如下:

复制代码

if(data <  current.data) {current = current.left;if(current == null) {parent.left = n;break;}
}

复制代码

Current = current.left 因此current = null; 继续执行上面的if语句判断是否为null的时候,因此就把37放入根节点为45的左节点上了。

5. 直接执行insert(3); 的时候,根节点不为空,所以就进入else语句的while语句中,由于当前的data = 3,所以执行如下if判断代码:

复制代码

if(data <  current.data) {current = current.left;if(current == null) {parent.left = n;break;}
}

复制代码

插入的节点值3 小于 根节点23,进入if语句里面执行,但是当前的current值如下:

所以当执行 current = current.left 的时候,那么current = 16的那个节点了,如下所示:

因此current 不等于null,所以就执行到下一次while循环,继续进入while中的if判断,由于当前的根节点是16,所以也就进入了if里面的代码去执行,在执行这句代码后:

current = current.left; 由上图可知:current = null;current就等于null了;再执行代码如下:

if(current == null) {parent.left = n;break;
}

就把节点3 插入到当前的根节点为16的左节点了。

6. 执行insert(99)的时候;当前的根节点23 小于 99,那么就进入else语句了,那么current值就等于如下:

当执行 current = current.right; 的时候 ,那么current 就等于如下:

再接着执行代码:

if(current == null) {parent.right = n;break;
}

如上图所示,current并不等于null,所以执行下一次while循环,继续进入while中的else语句,那么当前的current值如下:

当执行current = current.right;这句代码的时候,那么current 就等于 null了,所以执行if语句代码如下:

if(current == null) {parent.right = n;break;
}

就把99节点插入到当前的根节点为45节点的右节点了。

7. 执行 insert(22);的时候,由于根节点为23,所以节点22 小于 23,所以进入while中的if语句里面了,那么当前current值如下:

当执行 current = current.left; 的时候,那么current值变为如下所示:

所以执行 if语句代码如下:

if(current == null) {parent.left = n;break;
}

不等于null,所以斤进入while下一次循环,由于当前的根节点16 小于插入的节点22 ,所以就进入else语句了,那么当前的current值如下:

再执行这句代码 current = current.right; 那么current就等于null了;因此就把节点22插入到根节点为16上面的右节点上了;

以上是插入节点的整个流程!

二:遍历二叉查找树;

遍历二叉树的方法有三种,中序,先序和后序。

1. 中序;

如下图所示:

中序遍历使用递归的方式实现,该方法需要以升序访问树中的所有节点,先访问左子树,再访问根节点,最后访问右子树。

代码如下:

复制代码

// 中序遍历
function inOrder(node) {if(!(node == null)) {inOrder(node.left);console.log(node.show());inOrder(node.right);}
}

复制代码

代码分析如下:

JS所有代码如下:

复制代码

function Node(data,left,right) {this.data = data;this.left = left;this.right = right;this.show = show;
}function show() {return this.data;
}function BST() {this.root = null;this.insert = insert;this.inOrder = inOrder;
}function insert(data) {var n = new Node(data,null,null);if(this.root == null) {this.root = n;}else {var current = this.root;var parent;while(current) {parent = current;if(data <  current.data) {current = current.left;if(current == null) {parent.left = n;break;}}else {current = current.right;if(current == null) {parent.right = n;break;}}}}
}
// 中序遍历
function inOrder(node) {if(!(node == null)) {inOrder(node.left);console.log(node.show());inOrder(node.right);}
}
代码初始化如下:
var nums = new BST();
nums.insert(23);
nums.insert(45);
nums.insert(16);
nums.insert(37);
nums.insert(3);
nums.insert(99);
nums.insert(22);
inOrder(nums.root);

复制代码

2. 先序:先序遍历先访问根节点,然后以同样方式访问左子树和右子树。如下图所示:

代码如下:

复制代码

// 先序遍历 
function preOrder(node) {if(!(node == null)) {console.log(node.show());preOrder(node.left);preOrder(node.right);}
}

复制代码

JS所有代码如下:

复制代码

function Node(data,left,right) {this.data = data;this.left = left;this.right = right;this.show = show;
}
function show() {return this.data;
}
function BST() {this.root = null;this.insert = insert;this.inOrder = inOrder;
}
function insert(data) {var n = new Node(data,null,null);if(this.root == null) {this.root = n;}else {var current = this.root;var parent;while(current) {parent = current;if(data <  current.data) {current = current.left;if(current == null) {parent.left = n;break;}}else {current = current.right;if(current == null) {parent.right = n;break;}}}}
}
// 中序遍历
function inOrder(node) {if(!(node == null)) {inOrder(node.left);console.log(node.show());inOrder(node.right);}
}// 先序遍历 
function preOrder(node) {if(!(node == null)) {console.log(node.show());preOrder(node.left);preOrder(node.right);}
}
初始化代码如下:
var nums = new BST();
nums.insert(23);
nums.insert(45);
nums.insert(16);
nums.insert(37);
nums.insert(3);
nums.insert(99);
nums.insert(22);
console.log("--------------");
preOrder(nums.root);

复制代码

先序遍历打印如下:

3. 后序:后序遍历先访问叶子节点,从左子树到右子树,再到根节点,如下所示:

JS代码如下:

复制代码

// 后序遍历
function postOrder(node) {if(!(node == null)) {postOrder(node.left);postOrder(node.right);console.log("后序遍历"+node.show());}
}

复制代码

所有的JS代码如下:

复制代码

function Node(data,left,right) {this.data = data;this.left = left;this.right = right;this.show = show;
}function show() {return this.data;
}function BST() {this.root = null;this.insert = insert;this.inOrder = inOrder;
}function insert(data) {var n = new Node(data,null,null);if(this.root == null) {this.root = n;}else {var current = this.root;var parent;while(current) {parent = current;if(data <  current.data) {current = current.left;if(current == null) {parent.left = n;break;}}else {current = current.right;if(current == null) {parent.right = n;break;}}}}
}
// 中序遍历
function inOrder(node) {if(!(node == null)) {inOrder(node.left);console.log(node.show());inOrder(node.right);}
}// 先序遍历 
function preOrder(node) {if(!(node == null)) {console.log(node.show());preOrder(node.left);preOrder(node.right);}
}// 后序遍历
function postOrder(node) {if(!(node == null)) {postOrder(node.left);postOrder(node.right);console.log("后序遍历"+node.show());}
}
页面初始化如下:
var nums = new BST();
nums.insert(23);
nums.insert(45);
nums.insert(16);
nums.insert(37);
nums.insert(3);
nums.insert(99);
nums.insert(22);
console.log("--------------");
postOrder(nums.root);

复制代码

打印如下:

https://blog.csdn.net/m0_73633807/article/details/141037673?spm=1001.2100.3001.7377&utm_medium=distribute.pc_feed_blog_category.none-task-blog-classify_tag-1-141037673-null-null.nonecase&depth_1-utm_source=distribute.pc_feed_blog_category.none-task-blog-classify_tag-1-141037673-null-null.nonecase

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

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

相关文章

IObit Uninstaller Pro v13.6.0.5 绿色便携免安装版本 下载

功能非常强大好用的软件卸载清理工具 下载地址(资源制作整理不易&#xff0c;下载使用需付费&#xff0c;不能接受请勿浪费时间下载) 链接&#xff1a;https://pan.baidu.com/s/1I7lbixooii9ezSrp3X-y-w?pwd716l 提取码&#xff1a;716l

d3dcompiler_47.dll缺失的可能原因多种多样,那么d3dcompiler_47.dll缺失怎么修复

在数字世界的深处&#xff0c;d3dcompiler_47.dll文件扮演着至关重要的角色&#xff0c;它是Direct3D编译器的一部分&#xff0c;负责处理图形渲染和游戏运行中的关键任务。然而&#xff0c;当用户启动某个程序或游戏时&#xff0c;屏幕上突然弹出的错误提示“d3dcompiler_47.d…

苹果手机勿扰模式怎么关闭?4个方法快速关闭!

我们为了提升做事的效率以及保障休息的质量&#xff0c;在认真工作和学习&#xff0c;或者是晚上休息的时候&#xff0c;通常会打开苹果手机的勿扰模式。但当我们需要恢复苹果手机的消息通知时&#xff0c;苹果手机勿扰模式怎么关闭呢&#xff1f;今天&#xff0c;小编整理了4个…

机械学习—零基础学习日志(概率论总笔记2)

正态分布 高斯分布也叫做正态分布。假定事件A经过n次试验后发生了k次&#xff0c;把k的概率分布图画一下&#xff0c;就得到了一个中间鼓起&#xff0c;像倒扣的钟一样的对称图形。 18世纪&#xff0c;数学家棣莫弗和拉普拉斯把这种中间大&#xff0c;两头小的分布称为正态分布…

厨师帽佩戴识别摄像机

厨师帽佩戴识别摄像机 是一种用于识别厨师是否佩戴帽子的智能设备&#xff0c;其作用在于强制执行食品安全卫生标准&#xff0c;防止头发掉落入食物中。该摄像机利用人工智能和图像识别技术&#xff0c;能够识别厨师是否佩戴厨师帽。当摄像机检测到厨师未佩戴帽子时&#xff0c…

微信小程序中Towxml解析Markdown及html

一、Towxml Towxml 是一个让小程序可以解析Markdown、HTML的解析库。 二、引入 2.1 clone代码 git clone https://github.com/sbfkcel/towxml.git2.2 安装依赖 npm install2.3 打包 npm run build2.4 引入文件 将dist文件复制到微信小程序根目录&#xff0c;改名为towx…

Flutter中的Key

在Flutter 中&#xff0c;Key 是 几乎所有 widget 都具有的属性。为什么 widget 具有 Key 呢&#xff1f;Key的作用是什么&#xff1f; 什么是 Key Key是Widget、Element 和 SemanticNodes 的标识符。 Key 是Widget、Element 和 SemanticNodes的唯一标识。例如对于 Widget 在 …

数据结构之 “单链表“

&#xff08;1&#xff09;在顺表表中&#xff0c;如果是头插/删的时间复杂度是O(1)&#xff1b;尾插/删的时间复杂度是O(N) &#xff08;2&#xff09;增容一般是呈2倍的增长&#xff0c;势必会有一定的空间浪费。比如&#xff1a;申请了50个空间&#xff0c;只用了两个&#…

Type-C接口诱骗取电快充方案

Type-C XSP08Q 快充协议芯片是一种新型电源管理芯片&#xff0c;主要负责控制充电电流和电压等相关参数&#xff0c;从而实现快速充电功能。Type-C XSP08Q快充协议是在Type-C接口基础上&#xff0c;加入了XSP08Q协议芯片的支持&#xff0c;很大程度上提升了充电速度。 正常情况…

Linux——性能调优工具一览

一、CPU 1.调优工具 根据指标找工具 性能指标工具说明 平均负载 uptime、top uptime最简单、top提供了更全的指标 系统整体CPU使用率 vmstat、mpstat、top、sar、/proc/stat top、vmstat、mpstat只可以动态查看&#xff0c;而sar还可以记录历史数据 /proc/stat是其他性…

UE引擎内置插件信息 储存的位置

.uproject。图标文件可以让UE 引擎内置插件&#xff0c;配置更改,比如我希望我的DataSmithImporter插件是启用的。

STM32 ADC采样详解

Content 0x00 前言0x01 ADC配置0x02 滤波处理 0x00 前言 在单片机开发过程中&#xff0c;常常涉及到ADC的使用&#xff0c;市面上大部分便宜的传感器都是采用的ADC来获取其数据&#xff0c;如MQ-2 烟雾传感器、光敏传感器等等。 此类传感器工作原理为根据所采集到的数据变化…

大模型入门 ch01:大模型概述

本文是github上的大模型教程LLMs-from-scratch的学习笔记&#xff0c;教程地址&#xff1a;教程链接 STAGE 1&#xff1a; BUILDING 1. 数据准备与采样 LLM的预测过程&#xff0c;是一个不断预测下一个词&#xff08;准确的说是token&#xff09;的过程&#xff0c;每次根据输…

【C++八股题整理】内存布局、堆和栈、内存泄露、函数调用栈

C八股题整理 内存布局C中的内存分配情况堆和栈的内存有什么区别&#xff1f; 堆堆内存分配慢如何优化&#xff1f;内存池内存溢出和内存泄漏是什么&#xff1f;如何避免&#xff1f;内存碎片是什么&#xff1f;怎么解决&#xff1f; 栈为什么栈的访问效率比堆高&#xff1f;函数…

UI自动化测试 —— web端元素获取元素等待实践!

前言 Web UI自动化测试是一种软件测试方法&#xff0c;通过模拟用户行为&#xff0c;自动执行Web界面的各种操作&#xff0c;并验证操作结果是否符合预期&#xff0c;从而提高测试效率和准确性。 目的&#xff1a; 确保Web应用程序的界面在不同环境(如不同浏览器、操作系统)下…

【前缀和算法】--- 进阶题目赏析

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; 算法Journey 本篇我们来赏析前缀和算法的进阶题目。 &#x1f3e0; 和可被K整除的子数组 &#x1f4cc; 题目解析 和可被k整除的子数组 &#x1f4cc; …

记一次ssh伪终端修改为shell

问题 用户ssh进行连接后&#xff0c;默认为伪终端。 解决办法&#xff0c;可以先拿到终端shell&#xff0c;查看用户是否为/bin/bash&#xff1a; 不是/bin/bash&#xff0c;使用如下命令进行修改&#xff1a; chsh -s /bin/bash rootservice sshd restart

量化投资策略与技术学习PART1.1:量化选股之再谈多因子模型(二)

在上一个多因子模型中&#xff0c;我手动对各个因子进行了回测&#xff0c;但是数据结果并不是十分理想&#xff0c;难道基本面指标真的和股票走势关系不大么&#xff1f; 这里我还是准备再测试一下&#xff0c;策略如下&#xff1a; &#xff08;1&#xff09;首先我获取了一下…

codeforces Round 970 (Div. 3)(A-F)

文章目录 [Codeforces Round 970 (Div. 3)](https://codeforces.com/contest/2008)A-[Sakurakos Exam](https://codeforces.com/contest/2008/problem/A)B-[Square or Not](https://codeforces.com/contest/2008/problem/B)C-[Longest Good Array](https://codeforces.com/cont…

Ubuntu上安装配置(jdk/tomcat/ufw防火墙/mysql)+mysql卸载

jdk安装 1.上传jdk压缩包 详情&#xff1a; 下载rz服务&#xff08;lrzsz&#xff09;&#xff1a;sudo apt install lrzsz(在主用户root就不用sudo)下载压缩包&#xff1a;rz 2.解压jdk压缩包 &#xff1a; 详情&#xff1a; 在压缩包所在位置&#xff08;解压压缩使用看Li…