javascript算法之二叉搜索树的示例代码
这篇文章主要介绍了javascript算法之二叉搜索树的示例代码,具有一定的参考和学习JavaScript的价值,对JavaScript感兴趣的小伙伴们可以参考一下本篇文章
什么是二叉树
二叉树就是树的每个节点最多只能有两个子节点
什么是二叉搜索树
二叉搜索树在二叉树的基础上,多了一个条件,就是二叉树在插入值时,若插入值比当前节点小,就插入到左节点,否则插入到右节点;若插入过程中,左节点或右节点已经存在,那么继续按如上规则比较,直到遇到一个新的节点。
二叉搜索树的特性
二叉搜索树由于其独特的数据结构,使得其无论在增删,还是查找,时间复杂度都是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算法之二叉搜索树的示例代码的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

人脸检测识别技术已经是一个比较成熟且应用广泛的技术。而目前最为广泛的互联网应用语言非JS莫属,在Web前端实现人脸检测识别相比后端的人脸识别有优势也有弱势。优势包括减少网络交互、实时识别,大大缩短了用户等待时间,提高了用户体验;弱势是:受到模型大小限制,其中准确率也有限。如何在web端使用js实现人脸检测呢?为了实现Web端人脸识别,需要熟悉相关的编程语言和技术,如JavaScript、HTML、CSS、WebRTC等。同时还需要掌握相关的计算机视觉和人工智能技术。值得注意的是,由于Web端的计

Oracle中的DECODE函数是一种条件表达式,常用于在查询语句中根据不同的条件返回不同的结果。本文将详细介绍DECODE函数的语法、用法和示例代码。一、DECODE函数语法DECODE(expr,search1,result1[,search2,result2,...,default])expr:要进行比较的表达式或字段。search1,

Go语言的缩进规范及示例Go语言是一种由Google开发的编程语言,它以简洁、清晰的语法着称,其中缩进规范在代码的可读性和美观性方面起着至关重要的作用。本文将介绍Go语言的缩进规范,并通过具体的代码示例进行详细说明。缩进规范在Go语言中,缩进使用制表符(tab)而非空格。每级缩进为一个制表符,通常设置为4个空格的宽度。这样的规范统一了代码风格,使得团队合作编

随着互联网金融的迅速发展,股票投资已经成为了越来越多人的选择。而在股票交易中,蜡烛图是一种常用的技术分析方法,它能够显示股票价格的变化趋势,帮助投资者做出更加精准的决策。本文将通过介绍PHP和JS的开发技巧,带领读者了解如何绘制股票蜡烛图,并提供具体的代码示例。一、了解股票蜡烛图在介绍如何绘制股票蜡烛图之前,我们首先需要了解一下什么是蜡烛图。蜡烛图是由日本人

JavaScript教程:如何获取HTTP状态码,需要具体代码示例前言:在Web开发中,经常会涉及到与服务器进行数据交互的场景。在与服务器进行通信时,我们经常需要获取返回的HTTP状态码来判断操作是否成功,根据不同的状态码来进行相应的处理。本篇文章将教你如何使用JavaScript获取HTTP状态码,并提供一些实用的代码示例。使用XMLHttpRequest

js和vue的关系:1、JS作为Web开发基石;2、Vue.js作为前端框架的崛起;3、JS与Vue的互补关系;4、JS与Vue的实践应用。

PHP点操作符的运用与实例分析在PHP中,点操作符(“.”)是用来连接两个字符串的运算符,它在字符串拼接时非常常用并且十分灵活。通过使用点操作符,我们可以方便地将多个字符串连接起来,构成一个新的字符串。下面将通过实例分析来介绍PHP点操作符的运用。一、基本使用方法首先,我们来看一个基本的使用实例。假设有两个变量$str1和$str2,分别存储了两个字

JavaScript中的HTTP状态码获取方法简介:在进行前端开发中,我们常常需要处理与后端接口的交互,而HTTP状态码就是其中非常重要的一部分。了解和获取HTTP状态码有助于我们更好地处理接口返回的数据。本文将介绍使用JavaScript获取HTTP状态码的方法,并提供具体代码示例。一、什么是HTTP状态码HTTP状态码是指当浏览器向服务器发起请求时,服务
