当前位置:首页 > 日记 > 正文

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分,因为公式很简单,就几句话几个原则,但是遇到的问题是千变万化的,只有真正将理论付诸实践,经过各种实践的打磨蹂躏,才能真正理解它其中的奥秘。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

相关文章

NodeJS设计模式总结【单例模式,适

NodeJS设计模式总结【单例模式,适

设计模式,单例模式,装饰模式,适配器模式,观察者模式,本文实例讲述了NodeJS设计模式。分享给大家供大家参考,具体如下:1 . 单例模式顾名思义,单例就是保证一个类只有一个实例,实现的方法是,先判断实例是否存在,如果存在则直接返回,若不存在,则创建实…

WPS文字怎么删除表格后空白页

WPS文字怎么删除表格后空白页

删除表,文字,格后,方法,空白页,  表格后的空白页删不掉让人烦恼,那么表格后的空白页该怎样去掉呢?以下是小编给大家整理的WPS文字去掉表格后空白页的技巧,希望能帮到你!WPS文字删除表格后空白页的方法难道就真的没有办法去掉这可恶的空白页…

Spring AOP的实现原理详解及实例

Spring AOP的实现原理详解及实例

实现原理,详解,实例,电脑软件,Spring,Spring AOP的实现原理详解及实例spring 实现AOP是依赖JDK动态代理和CGLIB代理实现的。以下是JDK动态代理和CGLIB代理简单介绍 JDK动态代理:其代理对象必须是某个接口的实现,它是通过在运行期间创建一…

angular2+node.js express打包部署

angular2+node.js express打包部署

实战,电脑软件,node,express,js,Angular2我自己还在摸索学习中,本文介绍了angular2+node.js express打包部署的实战,分享给大家,也给自己留个笔记angular是客户端js,Node.js 是服务端JS,建立SPA 网站需要把这两者统一到一起。1、angular2项目…

怎么样用word绘制表格用word绘制表

怎么样用word绘制表格用word绘制表

绘制,步骤,方法,表格,电脑软件,  word已经普及人们的生活,可以用word来制作个人简历、制作1篇文章、制作1张电子小报亦或是论文等等,下面小编来教大家如何用word绘制1张简单的表格。word绘制表格的步骤这是我绘制的1张简单表格大家只要知道…

怎么恢复excel2010没有保存的文件

怎么恢复excel2010没有保存的文件

文件,恢复,电脑软件,  恢复excel2010没有保存的文件,有时我们太匆忙了,把Excel做到一半的时候我们忘记点击保存,就直接把它给关了,再打开的时候就老是显示不出来了,就没有了。以下是小编为您带来的关于恢复excel2010没有保存的文件,希望对您有…

PHP框架laravel的.env文件配置教程

PHP框架laravel的.env文件配置教程

配置,文件,框架,教程,电脑软件,前言大家应该都知道使用laravel框架开发PHP程序的时候,配置框架的.env文件是至关重要的,这个文件上需要配置数据库、数据库用户以及缓存等,下面来一起看看详细的配置教程。一、配置APP_KEYlaravel框架默认在.env…

PS怎么制作扇形文字?

PS怎么制作扇形文字?

文字,扇形,电脑软件,PS,今天为大家分享PS怎么制作扇形文字方法,很简单,只需几个步骤即可参考本文,来看看吧!步骤:1、选择&ldquo;横排文字工具&rdquo;;2、在文档中输入&ldquo;&rdquo;;3、选择属性栏中的&ldquo;变形&rdquo;按钮,选择下拉菜单中的&ldq…

使用AngularJS 跨站请求如何解决js

使用AngularJS 跨站请求如何解决js

请求,如何解决,电脑软件,AngularJS,jsonp,今天写东西的时候遇到了 一种情况 ,因为用的不是自己公司人员写的接口 ,而我要写的东西是抓别的网页上的接口所以出现了 一下这种情况 用 get请求出现拦截跨站请求资源 以下是解决办法,这是我的请求:…

在Word2007文档中如何设置自选图形

在Word2007文档中如何设置自选图形

文字,文档,图形,设置,如何设置,  在Word2007文档中,通过为自选图形设置文字环绕方式,可以使文字更合理地环绕在自选图形周围,从而使图文混排的文档更加规范、美观和经济。以下是小编为您带来的关于在Word2007文档中设置自选图形文字环绕,希望…

vuejs绑定class和style样式

vuejs绑定class和style样式

绑定,样式,电脑软件,vuejs,style,绑定Html Class我们可以传给 v-bind:class 一个对象,以动态地切换 class。注意 v-bind:class 指令可以与普通的 class 特性共存:<div class="static" v-bind:class="{ 'class-a': isA, 'class-b': isB…

excel2003规划求解的教程

excel2003规划求解的教程

教程,电脑软件,  Excel中如何操作规划求解呢?下面是小编带来的关于excel2003规划求解的教程,希望阅读过后对你有所启发!excel2003规划求解的教程:  规划求解步骤1:首先我们来讲一下EXCEL里面内置的单变量求解。规划求解步骤2:为了方便操作,…