我认为这社会上,也不差钱好多人,可能好多人也不差权力。可是我认为能得到这样的满足的也不多。 –郭小平<临汾红丝带学校校长>

​ 树是计算机科学中经经常使用到的一种数据结构。

树是一种非线性的数据结构,以分层的方式存储数据。

是被用来存储具有层级关系或有序的数据,比方文件系统中的文件。

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数据结构-树的更多相关文章

  1. JavaScript数据结构——树

    树:非顺序数据结构,对于存储需要快速查找的数据非常有用. 二叉树:二叉树中的节点最多只能有两个子节点(左侧子节点和右侧子节点).这些定义有助于我们写出更高效的向/从树中插入.查找和删除节点的算法. 二 ...

  2. JavaScript数据结构——树的实现

    在计算机科学中,树是一种十分重要的数据结构.树被描述为一种分层数据抽象模型,常用来描述数据间的层级关系和组织结构.树也是一种非顺序的数据结构.下图展示了树的定义: 在介绍如何用JavaScript实现 ...

  3. 学习javascript数据结构(四)——树

    前言 总括: 本文讲解了数据结构中的[树]的概念,尽可能通俗易懂的解释树这种数据结构的概念,使用javascript实现了树,如有纰漏,欢迎批评指正. 原文博客地址:学习javascript数据结构( ...

  4. 为什么我要放弃javaScript数据结构与算法(第八章)—— 树

    之前介绍了一些顺序数据结构,介绍的第一个非顺序数据结构是散列表.本章才会学习另一种非顺序数据结构--树,它对于存储需要快速寻找的数据非常有用. 本章内容 树的相关术语 创建树数据结构 树的遍历 添加和 ...

  5. JavaScript 数据结构与算法之美 - 非线性表中的树、堆是干嘛用的 ?其数据结构是怎样的 ?

    1. 前言 想学好前端,先练好内功,内功不行,就算招式练的再花哨,终究成不了高手. 非线性表(树.堆),可以说是前端程序员的内功,要知其然,知其所以然. 笔者写的 JavaScript 数据结构与算法 ...

  6. javascript数据结构与算法-- 二叉树

    javascript数据结构与算法-- 二叉树 树是计算机科学中经常用到的一种数据结构.树是一种非线性的数据结构,以分成的方式存储数据,树被用来存储具有层级关系的数据,比如文件系统的文件,树还被用来存 ...

  7. 为什么我要放弃javaScript数据结构与算法(第九章)—— 图

    本章中,将学习另外一种非线性数据结构--图.这是学习的最后一种数据结构,后面将学习排序和搜索算法. 第九章 图 图的相关术语 图是网络结构的抽象模型.图是一组由边连接的节点(或顶点).学习图是重要的, ...

  8. 为什么我要放弃javaScript数据结构与算法(第七章)—— 字典和散列表

    本章学习使用字典和散列表来存储唯一值(不重复的值)的数据结构. 集合.字典和散列表可以存储不重复的值.在集合中,我们感兴趣的是每个值本身,并把它作为主要元素.而字典和散列表中都是用 [键,值]的形式来 ...

  9. JavaScript数据结构——字典和散列表的实现

    在前一篇文章中,我们介绍了如何在JavaScript中实现集合.字典和集合的主要区别就在于,集合中数据是以[值,值]的形式保存的,我们只关心值本身:而在字典和散列表中数据是以[键,值]的形式保存的,键 ...

随机推荐

  1. Atitit.收银系统模块架构attilax 总结

    Atitit.收银系统模块架构attilax 总结 1. 常规收银系统模块结构1 1.1. 商品管理1 1.2. 会员系统1 1.3. 报表系统1 1.4. 会员卡系统1 1.5. 库存管理1 2.  ...

  2. Atitit.获取swing ui 按钮控件的id 与名字 与JPDA 调试体系

    Atitit.获取swing ui 按钮控件的id 与名字 与JPDA 调试体系 1. Swing Inspector是一个Java Swing/AWT用户界面分析和调试工具,功能与firebug类似 ...

  3. SQL——使用游标进行遍历

    前两天一个同事大叔问了这样一个问题,他要对表做个类似foreach的效果,问我怎么搞.我想了想,就拿游标回答他,当时事实上也没用过数据库中的游标,可是曾经用过ADO里面的,感觉应该几乎相同. 今天闲下 ...

  4. centos7系统备份与还原

    1. 前言 在使用Ubuntu之前,相信很多人都有过使用Windows系统的经历.如果你备份过Windows系统,那么你一定记忆犹新:首先需要找到一个备份工具(通常都是私有软件),然后重启电脑进入备份 ...

  5. SQL中使用视图的优点和缺点是什么

    视图的优点与缺点 在程序设计的时候必须先了解视图的优缺点,这样可以扬长避短,视图具有如下的一些优点: ● 简单性.视图不仅可以简化用户对数据的理解,也可以简化他们的操作.那些被经常使用的查询可以被定义 ...

  6. Doing Homework again(杭电1789)

    Doing Homework again Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  7. 内核交互--sysfs

    文档介绍:http://lxr.linux.no/linux+v2.6.37/Documentation/filesystems/sysfs.txt The sysfs Filesystem Sysf ...

  8. VMware虚拟机 Ubuntu 实用技巧 (1) -- 安装VMware Tool

    1.用VM安装Ubuntu后屏幕太小? 2.Ubuntu中的文本与window中的文本不能互相复制黏贴? 如果你遇到以上问题,可以通过在VMware里安装“VMware Tool”插件解决!! 安装步 ...

  9. 模拟 Ajax 上传

    ----------------view----------------------------------- <form method="post" action=&quo ...

  10. 通过 append() 和 prepend() 方法添加若干新元素

    在上面的例子中,我们只在被选元素的开头/结尾插入文本/HTML. 不过,append() 和 prepend() 方法能够通过参数接收无限数量的新元素.可以通过 jQuery 来生成文本/HTML(就 ...