javascript算法之二叉搜索树的示例代码
发布时间 - 2026-01-11 03:13:01 点击率:次什么是二叉树

二叉树就是树的每个节点最多只能有两个子节点
什么是二叉搜索树
二叉搜索树在二叉树的基础上,多了一个条件,就是二叉树在插入值时,若插入值比当前节点小,就插入到左节点,否则插入到右节点;若插入过程中,左节点或右节点已经存在,那么继续按如上规则比较,直到遇到一个新的节点。
二叉搜索树的特性
二叉搜索树由于其独特的数据结构,使得其无论在增删,还是查找,时间复杂度都是O(h),h为二叉树的高度。因此二叉树应该尽量的矮,即左右节点尽量平衡。
二叉搜索树的构造
要构造二叉搜索树,首先要构造二叉树的节点类。由二叉树的特点可知,每个节点类都有一个左节点,右节点以及值本身,因此节点类如下:
class Node {
constructor(key) {
this.key = key;
this.left = null;
this.right = null;
}
}
接着构造二叉搜索树
class Tree{
constructor(param = null) {
if (param) {
this.root = new Node(param);
} else {
this.root = null;
}
}
}
这里this.root就是当前对象的树。
二叉搜索树的新增
由二叉搜索树左子树比节点小,右子树别节点大的特点,可以很简单的写出二叉搜索树新增的算法,如下:
insert(key) {
if (this.root === null) {
this.root = new Node(key);
} else {
this._insertNode(this.root, key);
}
}
_insertNode(node, key) {
if (key < node.key) {
if (node.left === null) {
node.left = new Node(key);{1}
} else {
this._insertNode(node.left, key);{2}
}
} else if (key > node.key) {
if (node.right === null) {
node.right = new Node(key);{3}
} else {
this._insertNode(node.right, key);{4}
}
}
}
如上代码先判断新增的key与当前节点的key大小,如果小,就递归遍历左子节点,直到找到一个为null的左子节点;如果比当前节点大同理。如上代码{1}{2}{3}{4}之所以能改变this.root的值,是由于JavaScript函数是按值传递,而当参数是非基本类型时,例如这里的对象,其对象的值为内存,因此每次都会直接改变this.root的内容。
二叉搜索树的遍历
二叉搜索树分为先序、中序、后序三种遍历方式。
inOrderTraverse(callback) {
this._inOrderTraverse(this.root, callback);
}
_inOrderTraverse(node, callback) {
if (node) {
this._inOrderTraverse(node.left, callback);
callback(node.key);
this._inOrderTraverse(node.right, callback);
}
}
如上是中序遍历。
这里需要理解的一点是递归。要知道,函数的执行可以抽象为一种数据结构——栈。针对函数的执行,会维护一个栈,来存储函数的执行。函数在每一次递归时,都会将当前的执行环境入栈并记录执行的位置。以上述代码为例,有如下一个数据
其会从11开始,执行{1}入栈,然后进入7,接着执行{1}入栈,然后到5,执行{1}入栈,再到3,执行{1}入栈,此时发现节点3的左子节点为null,因此开始出栈,此时弹出节点3的执行环境,执行{2},{3},发现3的右侧子节点也为null,{3}的递归执行完毕,接着弹出节点5,执行{2}{3},接着弹出7,执行{2}{3}入栈,执行{3}时,发现节点7有右节点,因此继续执行{1},到节点8,再执行{1},8没有左子节点,{1}执行完毕,执行{2}{3},以此类推。
而前序与中序的不同点在于其先访问节点本身,也就是代码的执行顺序为 2 1 3。
后序同理,执行顺序为1 3 2
不难发现,无论前中后序,永远都是先递归左节点,当左节点遍历完毕时再弹出栈,遍历有节点。他们唯一不同的点在与访问该节点本身的时机。
二叉搜索树的查找
查找很简单,根据左子节点比该节点小,右子节点比该节点大的原则进行循环判断即可。
search(value) {
if (this.root) {
if (value === this.root.key) {
return true;
} else {
return this._searchNode(value, this.root);
}
}
throw new Error('this.root 不存在');
}
_searchNode(value, node) {
if (!node) {
return false;
}
if (value === node.key) {
return true;
}
if (value > node.key) {
return this._searchNode(value, node.right);
} else if (value < node.key) {
return this._searchNode(value, node.left);
}
}
二叉搜索树的删除
删除较为复杂,需要根据不同情况判断
首先判断该节点是否有左子树,如果没有左子节树,则直接将右子树的根节点替换被删除节点;
如果有,则将右子树的最小节点替换被删除节点;
remove(key) {
this._removeNode(this.root, key);
}
_removeNode(node, value) {
if (!node) {
return null;
}
if (value > node.key) {
node.right = this._removeNode(node.right, value);
} else if (value < node.key) {
node.left = this._removeNode(node.left, value);
} else {
// 如果没有左子树,那么将右子树根节点作为替换节点
if (!node.left) {
return node.right;
// 如果存在左子树,那么取右子树最小节点作为替换节点
} else if (node.left) {
return this._minNode(node.right);
}
}
}
总结
总的来说,通过这次简单的二叉搜索树的学习,让我重新认识了递归,以前对于递归的理解只是一些简单的理论概念,这次深入实践让我对递归的理解又加深了许多。
这让我想到了数学的学习,数学的理论公式是很容易记住掌握的,如果说对一个知识点的掌握满分是十分,那么直到真正去实践它之前,只看公式的掌握只能是2分,因为公式很简单,就几句话几个原则,但是遇到的问题是千变万化的,只有真正将理论付诸实践,经过各种实践的打磨蹂躏,才能真正理解它其中的奥秘。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# javascript
# 二叉搜索树
# 二叉树搜索算法
# 二叉树
# javascript数据结构之二叉搜索树实现方法
# Javascript实现从小到大的数组转换成二叉搜索树
# JavaScript实现二叉搜索树
# 如何利用JavaScript实现二叉搜索树
# 面向JavaScript入门初学者的二叉搜索树算法教程
# JavaScript二叉搜索树构建操作详解
# 子树
# 递归
# 遍历
# 弹出
# 很简单
# 数据结构
# 如果没有
# 其先
# 都是
# 我想
# 几个
# 让我
# 都有
# 基础上
# 我对
# 付诸实践
# 以此类推
# 很容易
# 不存在
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何基于云服务器快速搭建网站及云盘系统?
企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?
Linux后台任务运行方法_nohup与&使用技巧【技巧】
西安市网站制作公司,哪个相亲网站比较好?西安比较好的相亲网站?
如何批量查询域名的建站时间记录?
如何撰写建站申请书?关键要点有哪些?
Laravel怎么使用Blade模板引擎_Laravel模板继承与Component组件复用【手册】
微信小程序 scroll-view组件实现列表页实例代码
Linux安全能力提升路径_长期防护思维说明【指导】
Edge浏览器怎么启用睡眠标签页_节省电脑内存占用优化技巧
Laravel如何实现邮箱地址验证功能_Laravel邮件验证流程与配置
Python3.6正式版新特性预览
个人网站制作流程图片大全,个人网站如何注销?
如何做网站制作流程,*游戏网站怎么搭建?
网站优化排名时,需要考虑哪些问题呢?
Laravel怎么解决跨域问题_Laravel配置CORS跨域访问
如何在阿里云域名上完成建站全流程?
学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?
如何用AWS免费套餐快速搭建高效网站?
Laravel控制器是什么_Laravel MVC架构中Controller的作用与实践
青岛网站建设如何选择本地服务器?
图册素材网站设计制作软件,图册的导出方式有几种?
文字头像制作网站推荐软件,醒图能自动配文字吗?
如何在 React 中条件性地遍历数组并渲染元素
Laravel如何集成Inertia.js与Vue/React?(安装配置)
Claude怎样写约束型提示词_Claude约束提示词写法【教程】
网页制作模板网站推荐,网页设计海报之类的素材哪里好?
网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?
如何在万网主机上快速搭建网站?
如何在云主机上快速搭建网站?
Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】
浏览器如何快速切换搜索引擎_在地址栏使用不同搜索引擎【搜索】
Laravel怎么配置自定义表前缀_Laravel数据库迁移与Eloquent表名映射【步骤】
如何快速搭建二级域名独立网站?
清除minerd进程的简单方法
佛山网站制作系统,佛山企业变更地址网上办理步骤?
香港网站服务器数量如何影响SEO优化效果?
如何快速生成凡客建站的专业级图册?
MySQL查询结果复制到新表的方法(更新、插入)
如何确认建站备案号应放置的具体位置?
javascript如何操作浏览器历史记录_怎样实现无刷新导航
使用Dockerfile构建java web环境
Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载
详解Huffman编码算法之Java实现
网站制作免费,什么网站能看正片电影?
音乐网站服务器如何优化API响应速度?
Android中Textview和图片同行显示(文字超出用省略号,图片自动靠右边)
Bootstrap整体框架之CSS12栅格系统
如何在不使用负向后查找的情况下匹配特定条件前的换行符
Linux网络带宽限制_tc配置实践解析【教程】

