JavaScript数据结构-树
我认为这社会上,也不差钱好多人,可能好多人也不差权力。可是我认为能得到这样的满足的也不多。 –郭小平<临汾红丝带学校校长>
树是计算机科学中经经常使用到的一种数据结构。
树是一种非线性的数据结构,以分层的方式存储数据。
是被用来存储具有层级关系或有序的数据,比方文件系统中的文件。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlnYW5nMjU4NTExNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="树" title="">
二叉树
二叉树,每一个节点最多有两个子树的树结构。
二叉树是一种特殊的树,也是一个连通的无环图。
二叉查找树
二叉查找树是一种特殊的二叉树,其相对较小的值保存在左节点中。较大的值保存在右节点中。这一特性使其查找效率非常高。
实现二叉查找树
假设待插入节点小于(大于)当前节点,且当前节点的左(右)节点为null,则将待插入节点插入到当前节点的左(右)节点位置上,结束循环。否则,将当前节点的左(右)节作为当前节点继续下次循环。
/**
* 节点定义
* @param data 数据
* @param left 左子树
* @param right 右子树
* @constructor
*/
function Node(data, left, right) {
this.data = data;
this.left = left;
this.right = right;
}
Node.prototype.show = function() {
return this.data;
};
/**
* 二叉查找树定义
* @constructor
*/
function BST() {
this.root = null;
}
/**
* 插入节点
* @constructor
*/
BST.prototype.insert = function(data) {
// 待插入节点
var node = new Node(data, null, null);
if(this.root === null) {
this.root = node;
} else {
var currentNode = this.root;
var parent;
while(true) {
parent = currentNode;
// 待插入节点小于当前节点
if(data < currentNode.data) {
// 将其左子树作为当前节点
currentNode = currentNode.left;
if(currentNode === null) {
parent.left = node;
break;
}
}else {
// 将其右子树作为当前节点
currentNode = currentNode.right;
if(currentNode === null) {
parent.right = node;
break;
}
}
}
}
return this; // 支持链式调用
};
- 中序:先訪问左子树。再訪问根节点,最后訪问右字数。以升序訪问BST上全部节点;(左==>根==>右)
- 先序:先訪问根节点,然后以相同方式訪问左子树和右子树;(根==>左==>右)
- 后序:先訪问叶子节点,从左子树到右子树。再到根节点。
(左==>右==>根)
BST.prototype.order = function(node, type) {
switch (type) {
case "inorder": // 中序
if(node != null) {
/*左==>根==>右*/
this.order(node.left, type);
console.log(node.show());
this.order(node.right, type);
}
break;
case "preorder": // 先序
if(node != null) {
/*根==>左==>右*/
console.log(node.show());
this.order(node.left, type);
this.order(node.right, type);
}
break;
case "postorder": // 后序
if(node != null) {
/*左==>右==>根*/
this.order(node.left, type);
this.order(node.right, type);
console.log(node.show());
}
break;
}
};
測试
var bst = new BST();
bst.insert(32).insert(11).insert(2)
.insert(13).insert(75)
.insert(66).insert(88);
bst.order(bst.root, "inorder"); // 中序
bst.order(bst.root, "preorder"); // 先序
bst.order(bst.root, "postorder"); // 后序
查询最小值和最大值
- 最小值:遍历左子树。直到找到最后一个节点。
- 最大值:遍历右子树,直到找到最后一个节点。
/**
* 获取最小值:左子树的最后一个节点
*/
BST.prototype.getMin = function(node) {
var currentNode = node || this.root;
while(currentNode.left !== null) {
currentNode = currentNode.left;
}
return currentNode;
};
/**
* 获取最小值:右子树的最后一个节点
*/
BST.prototype.getMax = function(node) {
var currentNode = node || this.root;
while(currentNode.right !== null) {
currentNode = currentNode.right;
}
return currentNode;
};
console.log(bst.getMin().data); // 2
console.log(bst.getMax().data); // 88
查找某节点
/**
* 查找某节点
* @param data 数据
*/
BST.prototype.find = function(data) {
var currentNode = this.root;
while(currentNode !== null) {
if(data === currentNode.data) {
return currentNode;
}
currentNode = (data < currentNode.data) ?
currentNode.left : currentNode.right;
}
return null;
};
console.log(bst.find(66)); // Node { data: 66, left: null, right: null }
console.log(bst.find(99)); // null
删除节点
- 假设待删除节点为叶子节点。则直接删除它;
- 假设待删除节点仅仅有一个子节点,则直接将待删除节点的父节点指向其子节点;
- 假设待删除节点包括两个子节点,我们选择右子树上的最小值创建一个暂时节点,然后拷贝到待删节点。然后删除最小值节点。
/**
* 移除指定数据节点
* @param data
*/
BST.prototype.remove = function(node, data) {
node = node || this.root;
if(data === null) {
// 待删除节点不存在
return node;
}
if(node.data === data) {
// 无子节点
if(node.left === null && node.right === null) {
return null;
}
// 仅仅有右节点,无左节点
if(node.left === null) {
return node.right;
}
// 仅仅有左节点。无右节点
if(node.right === null) {
return node.left;
}
// 存在两个节点
var minNode = this.getMin(node.right);
console.log(minNode);
node.data = minNode.data;
node.right = this.remove(node.right, minNode.data);
}else if( node.data > data) {
node.left = this.remove(node.left, data);
}else if( node.data < data){
node.right = this.remove(node.right, data);
}
return node;
};
总结
树,在计算机科学中体现的特别多 。
如。我们熟悉的DOM树。数据库底层经经常使用到的B树等等。树能非常好的保证字典序,存储词典的空间压缩率高, 能做前缀搜索。
抽象地说,基本上有序列的地方就能够应用树,由于树结构即是一种序列索引结构。
JavaScript数据结构-树的更多相关文章
- JavaScript数据结构——树
树:非顺序数据结构,对于存储需要快速查找的数据非常有用. 二叉树:二叉树中的节点最多只能有两个子节点(左侧子节点和右侧子节点).这些定义有助于我们写出更高效的向/从树中插入.查找和删除节点的算法. 二 ...
- JavaScript数据结构——树的实现
在计算机科学中,树是一种十分重要的数据结构.树被描述为一种分层数据抽象模型,常用来描述数据间的层级关系和组织结构.树也是一种非顺序的数据结构.下图展示了树的定义: 在介绍如何用JavaScript实现 ...
- 学习javascript数据结构(四)——树
前言 总括: 本文讲解了数据结构中的[树]的概念,尽可能通俗易懂的解释树这种数据结构的概念,使用javascript实现了树,如有纰漏,欢迎批评指正. 原文博客地址:学习javascript数据结构( ...
- 为什么我要放弃javaScript数据结构与算法(第八章)—— 树
之前介绍了一些顺序数据结构,介绍的第一个非顺序数据结构是散列表.本章才会学习另一种非顺序数据结构--树,它对于存储需要快速寻找的数据非常有用. 本章内容 树的相关术语 创建树数据结构 树的遍历 添加和 ...
- JavaScript 数据结构与算法之美 - 非线性表中的树、堆是干嘛用的 ?其数据结构是怎样的 ?
1. 前言 想学好前端,先练好内功,内功不行,就算招式练的再花哨,终究成不了高手. 非线性表(树.堆),可以说是前端程序员的内功,要知其然,知其所以然. 笔者写的 JavaScript 数据结构与算法 ...
- javascript数据结构与算法-- 二叉树
javascript数据结构与算法-- 二叉树 树是计算机科学中经常用到的一种数据结构.树是一种非线性的数据结构,以分成的方式存储数据,树被用来存储具有层级关系的数据,比如文件系统的文件,树还被用来存 ...
- 为什么我要放弃javaScript数据结构与算法(第九章)—— 图
本章中,将学习另外一种非线性数据结构--图.这是学习的最后一种数据结构,后面将学习排序和搜索算法. 第九章 图 图的相关术语 图是网络结构的抽象模型.图是一组由边连接的节点(或顶点).学习图是重要的, ...
- 为什么我要放弃javaScript数据结构与算法(第七章)—— 字典和散列表
本章学习使用字典和散列表来存储唯一值(不重复的值)的数据结构. 集合.字典和散列表可以存储不重复的值.在集合中,我们感兴趣的是每个值本身,并把它作为主要元素.而字典和散列表中都是用 [键,值]的形式来 ...
- JavaScript数据结构——字典和散列表的实现
在前一篇文章中,我们介绍了如何在JavaScript中实现集合.字典和集合的主要区别就在于,集合中数据是以[值,值]的形式保存的,我们只关心值本身:而在字典和散列表中数据是以[键,值]的形式保存的,键 ...
随机推荐
- CSS3怎样实现超出指定文本以省略号显示效果
作者:zhanhailiang 日期:2014-10-24 不做前端非常久了,今天从重构师那里了解到CSS3已经能够实现非常多以往必须通过JS才干实现的效果,如渐变,阴影,自己主动截断文本展示省略号等 ...
- 硬件(MAC)地址的概念及作用
概念:MAC地址就是在媒体接入层上使用的地址,也叫物理地址.硬件地址或链路地址,其被固化在适配器的ROM中. 可见MAC地址实际上就是适配器地址或适配器标识符.当某台计算机使用某块适配器后,适配器上的 ...
- [原创]FreeSWITCH命令:uuid_dual_transfer
该篇文章主要介绍FreeSWITCH的API命令uuid_dual_transfer的用法. 命令介绍 该命令用于同时将两条腿进行转移,并且是可以转移到不同的方向. -USAGE: <A-des ...
- Linux系统中磁盘block和windos中的簇一个意思
block就是几个连续扇区组成一个block,每个分区可以设置block大小,好比一个txt只有2字节,但是这个分区的block为4K,那么其实这个txt需要4k来存储(所以大文件block设置大比较 ...
- VS2017 - Winform 简单托盘小程序
界面比较简单,主要两个button 一个NotifyIcon 和 右键菜单 控件, NotifyIcon 属性,如下: 并为NotifyIcon指定了DoubleClick事件: 主窗体增加两个事件: ...
- 辛星浅析Linux中的postfix
Postfix是眼下Linux下主流的邮件server,也就是MTA,主要用来实现SMTP协议,它能够兼容sendmail.而postfix也是为了改进sendmail而制作产生的. 通常来说.pos ...
- 大数据(4) - HDFS常用的shell操作
注意:这次使用的是第二部分安装的集群,不是高可用集群 为了方便,开发,必须写集群脚本,试想集群的机器是100台以上,而不是3台的情况.... 集群启动脚本 vim /home/admin/tools/ ...
- 001windows已遇到一个关键性问题 一分钟后自动重启
重装了系统Window7,出现了如题的提示"windows已遇到一个关键性问题 一分钟后自动重启" 查找原因: 通过事件管理器可以查看如上提示遇到的问题.一般是因为一些系统的服务没 ...
- wchar与char字符转换的探究
在Xcode 模拟器环境下.測试wchar_t与char的转换: void convert_test() { setlocale(LC_ALL, "zh_CN.UTF-8"); c ...
- 浅谈.net平台下深拷贝和浅拷贝
在.net类库中,对象克隆广泛存在于各种类型的实现中,凡是实现了ICloneable接口的类型都具备克隆其对象实例的能力.所以本文讲述的深拷贝和浅拷贝也是在实现ICloneable接口的基础上进行的 ...