JavaScript数据结构——树
BST 存在一个问题:取决于添加的节点树,树的一条边可能会非常深;也就是说,树的一条分支会有很多层,二其他的分支却只有几层。这会在需要在某条边上添加、移除和搜索某个节点时引起一些性能问题。
|
术语
|
解释
|
|
节点
|
树中的每个元素
|
|
根节点
|
树顶部的节点,没有父节点
|
|
内部节点
|
至少有一个子节点的节点
|
|
外部节点(叶节点)
|
没有子元素的节点
|
|
子树
|
由节点和它的后代构成
|
|
深度
|
节点的一个属性,取决于它的祖先节点的数量
|
|
高度
|
取决于所有节点深度的最大值
|


|
序号
|
方法
|
说明
|
|
1
|
insert(key) | 向树中插入一个新的键 |
|
2
|
search(key) | 在树中查找一个键,如果节点存在,则返回 true;如果不存在,则返回 false |
|
3
|
inOrderTraverse | 通过中序遍历方式遍历所有节点 |
|
4
|
preOrderTraverse | 通过先序遍历方式遍历所有节点 |
|
5
|
postOrderTraverse | 通过后序遍历方式遍历所有节点 |
|
6
|
min |
返回树种最小的值/键
|
|
7
|
max | 返回树种最大的值/键 |
|
8
|
remove(key) | 从树中移除某个键 |
function BinarySearchTree() {
// 辅助类Node定义
var Node = function(key) {
this.key = key;
this.left = null;
this.right = null;
}
var root = null;
// 向树中插入一个新的键
this.insert = function(key) {
var newNode = new Node(key);
if (root === null) {
root = newNode;
} else {
insertNode(root, newNode); // 私有的辅助函数
}
}
this.insertNode = function(node, newNode) {
if (newNode.key < node.key) {
if (node.left === null) {
node.left = newNode;
} else {
insertNode(node.left, newNode); // 如果有左侧子节点,则通过递归调用继续找到树的下一层
}
} else {
if (node.right === null) {
node.right = newNode;
} else {
insertNode(node.right, newNode); // 如果有右侧子节点,则通过递归调用继续找到树的下一层
}
}
}
/* 中序遍历
* inOrderTraverse方法接收一个回调函数作为参数。
* 回调函数用来定义我们对遍历到的每个节点进行的操作(也叫访问者模式)
*/
this.inOrderTraverse = function(callback) {
inOrderTraverseNode(root, callback);
}
this.inOrderTraverseNode = function(node, callback) {
if (node !== null) {
inOrderTraverseNode(node.left, callback);
callback(node.key);
inOrderTraverseNode(node.right, callback);
}
}
// 先序遍历
this.preOrderTraverse = function(callback) {
preOrderTraverseNode(root, callback);
}
this.preOrderTraverseNode = function(node, callback) {
if (node !== null) {
callback(node.key);
preOrderTraverseNode(node.left, callback);
preOrderTraverseNode(node.right, callback);
}
}
// 后序遍历
this.postOrderTraverse = function(allback) {
postOrderTraverseNode(root, callback);
}
this.postOrderTraverseNode = function(node, callback) {
if (node !== null) {
postOrderTraverseNode(node.left, callback);
postOrderTraverseNode(node.right, callback);
callback(node.key);
}
}
// 搜索树中的最小值
this.min = function() {
return minNode(root);
}
var minNode = function(node) {
if (node) {
while (node && node.left !== null) {
node = node.lfet;
}
return node.key;
}
return null;
}
// 搜索树中的最大值
this.max = function() {
return maxNode(root);
}
this.maxNode = function(node) {
if (node) {
while (node && node.right !== null) {
node = node.right;
}
return node.key;
}
return null;
}
// 搜索树中的特定值
this.search = function(key) {
return searchNode(root, key);
}
var searchNode = function(node, key) {
if (node === null) {
return false;
}
if (key < node.key) {
return searchNode(node.left ,key);
} else if (key > node.key) {
return searchNode(node.right, key);
} else {
return true;
}
}
// 从树中移除某个键
this.remove = function(key) {
root = removeNode(root, key); // root被赋值为removeNode方法的返回值
}
var removeNode = function(node, key) {
if (node === null) { // 键不存在于树中,则返回null
return null;
}
if (key < node.key) { // 如果要找的键比当前节点的值小,就沿着树的左边找到下一个节点
node.left = removeNode(node.left, key);
return node;
} else if (key > node.key) { // 如果要找的键比当前节点的值大,就沿着树的左边找到下一个节点
node.right = removeNode(node.right, key);
return node;
} else { // 键等于node.key
// 第一种情况——一个叶节点
if (node.left === null && node.right === null) {
node = null;
return node;
}
// 第二种情况——一个只有一个子节点的节点
if (node.left === null) {
node = node.right;
return node;
} else if (node.right === null) {
node = node.left;
return node;
}
// 第三种情况——一个有两个子节点的节点
var aux = findMinNode(node.right);
node.key = aux.key; // 用右侧子树中的最小节点的键去更新这个节点的值
node.right = removeNode(node.right, aux.key); // 移除右侧子树中的最小节点
return node;
}
}
}
BinarySearchTree.js
JavaScript数据结构——树的更多相关文章
- JavaScript数据结构——树的实现
在计算机科学中,树是一种十分重要的数据结构.树被描述为一种分层数据抽象模型,常用来描述数据间的层级关系和组织结构.树也是一种非顺序的数据结构.下图展示了树的定义: 在介绍如何用JavaScript实现 ...
- JavaScript数据结构-树
我认为这社会上,也不差钱好多人,可能好多人也不差权力.可是我认为能得到这样的满足的也不多. –郭小平<临汾红丝带学校校长> 树是计算机科学中经经常使用到的一种数据结构. 树是一种非线性 ...
- 学习javascript数据结构(四)——树
前言 总括: 本文讲解了数据结构中的[树]的概念,尽可能通俗易懂的解释树这种数据结构的概念,使用javascript实现了树,如有纰漏,欢迎批评指正. 原文博客地址:学习javascript数据结构( ...
- 为什么我要放弃javaScript数据结构与算法(第八章)—— 树
之前介绍了一些顺序数据结构,介绍的第一个非顺序数据结构是散列表.本章才会学习另一种非顺序数据结构--树,它对于存储需要快速寻找的数据非常有用. 本章内容 树的相关术语 创建树数据结构 树的遍历 添加和 ...
- JavaScript 数据结构与算法之美 - 非线性表中的树、堆是干嘛用的 ?其数据结构是怎样的 ?
1. 前言 想学好前端,先练好内功,内功不行,就算招式练的再花哨,终究成不了高手. 非线性表(树.堆),可以说是前端程序员的内功,要知其然,知其所以然. 笔者写的 JavaScript 数据结构与算法 ...
- javascript数据结构与算法-- 二叉树
javascript数据结构与算法-- 二叉树 树是计算机科学中经常用到的一种数据结构.树是一种非线性的数据结构,以分成的方式存储数据,树被用来存储具有层级关系的数据,比如文件系统的文件,树还被用来存 ...
- 为什么我要放弃javaScript数据结构与算法(第九章)—— 图
本章中,将学习另外一种非线性数据结构--图.这是学习的最后一种数据结构,后面将学习排序和搜索算法. 第九章 图 图的相关术语 图是网络结构的抽象模型.图是一组由边连接的节点(或顶点).学习图是重要的, ...
- 为什么我要放弃javaScript数据结构与算法(第七章)—— 字典和散列表
本章学习使用字典和散列表来存储唯一值(不重复的值)的数据结构. 集合.字典和散列表可以存储不重复的值.在集合中,我们感兴趣的是每个值本身,并把它作为主要元素.而字典和散列表中都是用 [键,值]的形式来 ...
- JavaScript数据结构——字典和散列表的实现
在前一篇文章中,我们介绍了如何在JavaScript中实现集合.字典和集合的主要区别就在于,集合中数据是以[值,值]的形式保存的,我们只关心值本身:而在字典和散列表中数据是以[键,值]的形式保存的,键 ...
随机推荐
- ASP.NET Web API路由规
默认的规则 在ASP.NET MVC4中 global.asax.cs代码中并无注册默认路由规则的代码 代码如下: public class WebApiApplication : System.We ...
- input[type=text]点击之后无边框, 一进页面就显示光标
1.input[type=text]点击之后无边框 :outline:none; 2. 一进页面就显示光标: <script Language="javascript"> ...
- weblogic部署ssh2应用出现异常
一般在domains\your_Domain\bin\startWebLogic.cmd 中找到set CLASSPATH=%CLASSPATH%;%MEDREC_WEBLOGIC_CLASSPATH ...
- linux 下echo命令写入文件内容
http://blog.csdn.net/xukai871105/article/details/35834703 echo "Raspberry" > test.txt
- SQL语句大全(mysql,sqlserver,oracle)
SQL语句大全 --语句功能--数据操作SELECT --从数据库表中检索数据行和列-selectINSERT --向数据库表添加新数据行-insertDELETE --从数据库表中删除数据行-del ...
- windows系统常见端口和木马默认使用端口
dos命令netstat比较好用,能比较全的看到自己开放的端口及状态一般我用netstat -a端口:0服务:Reserved说明:通常用于分析操作系统.这一方法能够工作是因为在一些系统中“0”是无效 ...
- 服务器端与客户端TCP连接入门(一)
Java中使用Socket(即套接字)完成TCP程序的开发 服务器端使用ServerSocket接收客户端的连接请求,每一个客户端都使用一个Socket对象表示 在服务器端每次运行时都要使用accep ...
- jQuery 中的 Ajax
jQuery 对 Ajax 操作进行了封装, 在 jQuery 中最底层的方法时 $.ajax(), 第二层是 load(), $.get() 和 $.post(), 第三层是 $.getScript ...
- 标签navtab
创建navtab 创建一个navtab有以下两种方式: 1.Data属性:DOM添加属性data-toggle="navtab"后,单击触发. a链接示例: <a href= ...
- ACM - 动态规划专题 题目整理
CodeForces 429B Working out 预处理出从四个顶点到某个位置的最大权值,再枚举相遇点,相遇的时候只有两种情况,取最优解即可. #include<iostream> ...