树结构之JavaScript
对于数据结构“树”,想必大家都熟悉,今儿,我们就再来回顾一下数据结构中的二叉树与树,并用JavaScript实现它们。
ps:树结构在前端中,很多地方体现得淋漓尽致,如Vue的虚拟DOM以及冒泡等等。
| 二叉树 |
--概念--
二叉树是一种树形结构,它的特点是每个结点至多只有两棵子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能任意颠倒。
如下,就是一棵二叉树(注:下文二叉树相关例子,都以该二叉树为例):

且,遍历二叉树(traversing binary tree)有三种常用方式,如下:
1)、先序遍历二叉树 (根左右)
若二叉树为空,则空操作;否则
--访问根结点;
--先序遍历左子树;
--先序遍历右子树。
例如,上述例子中的二叉树,遍历结果如下:

2)、中序遍历二叉树(左根右)
若二叉树为空,则空操作;否则
--中序遍历左子树;
--访问根结点;
--中序遍历右子树。
例如,上述例子中的二叉树,遍历结果如下:

3)、后序遍历二叉树(左右根)
若二叉树为空,则空操作;否则
--后序遍历左子树;
--后序遍历右子树;
--访问根结点。
例如,上述例子中的二叉树,遍历结果如下:

好了,了解了二叉树以及遍历方式,那么,接下来我们就一起用JavaScrip来实现下吧,当然采用链式存储结构。
首先,利用JavaScript构造函数建立二叉树结点,如下:
function TreeNode(){
this.data = null;//该节点数据
this.lchild = null;//左子树
this.rchild = null;//右子树
};
然后,我们可以通过遍历二叉树的算法,构建一棵二叉树,如下,采用先序序列建立一棵二叉树方法:
/*
*method:采用先序序列建立二叉树
*@params: nodeList(Array) --树节点,以先序序列存入数组中,null代表空节点
*/
TreeNode.createBiTree = function(nodeList){
var i = 0;
return (function getNode(){
var node = null,
val = nodeList[i++];
if(!val){
node = null;
}else{
node = new TreeNode();
node.data = val;
node.lchild = getNode();
node.rchild = getNode();
}
return node;
})();
};
最后,就是遍历一棵二叉树咯,分别为先序遍历(PreOrderTraverse)、中序遍历(InOrderTraverse)以及后序遍历(PostOrderTraverse),如下:
TreeNode.prototype = {
constructor: TreeNode,
_PreOrderTraverse: function(node){
if(node){
console.log(node.data);
this._PreOrderTraverse(node.lchild);
this._PreOrderTraverse(node.rchild);
}
},
PreOrderTraverse: function(){
console.log('PreOrder:');
this._PreOrderTraverse(this);
},
_InOrderTraverse: function(node){
if(node){
this._InOrderTraverse(node.lchild);
console.log(node.data);
this._InOrderTraverse(node.rchild);
}
},
InOrderTraverse: function(){
console.log('InOrder:');
this._InOrderTraverse(this);
},
_PostOrderTraverse: function(node){
if(node){
this._PostOrderTraverse(node.lchild);
this._PostOrderTraverse(node.rchild);
console.log(node.data);
}
},
PostOrderTraverse: function(){
console.log('PostOrder:');
this._PostOrderTraverse(this);
}
};
代码稍长,请自行打开
好了,利用上述二叉树例子,我们可以自行测试下:
var treeNode = null,
nodeList = ['A', 'B', 'C', null, null, 'D', 'E', null, 'G', null, null, 'F', null, null, null];
//getting a binary tree from nodeList
treeNode = TreeNode.createBiTree(nodeList);
//traversing the tree of treeNode
treeNode.PreOrderTraverse();//ABCDEGF
treeNode.InOrderTraverse();//CBEGDFA
treeNode.PostOrderTraverse();//CGEFDBA
| 树 |
--概念--
树是n(n>=0)个结点的有限集。在任意一棵非空树中,有且仅有一个特定的称为根(root)的结点,当n>1时,其余结点可分为m(m>0)个互不相交的有限集,其中每个集合本身又是一棵树,称为根的子树。当然,二叉树肯定属于树咯。
如下,就是一棵树(注:下文树的相关例子,都以该树为例):

且,遍历一棵多孩子树,有两种常用遍历方式,如下:
1) 、先根遍历,和深度优先搜索(Depth_First Search)遍历类似。都是利用栈来遍历元素,如下:

2) 、按层次遍历,和广度优先搜索(Breadth_First Search)遍历类似。都是利用队列来遍历元素,如下:

好了,了解了树以及遍历方式,那么,接下来我们就一起用JavaScrip来实现下吧,当然也是采用链式存储结构。
首先,利用JavaScript建立树结点,如下:
/*
*@Params: data --节点数据
children -- 所有孩子结点
*/
function TreeNode(data, children){
if(!(this instanceof TreeNode)){
return new TreeNode(data, children);
}
this.data = data || null;
this.children = children || [];
};
根据上述TreeNode构造函数,我们可以将例子中的树,表示如下:
var treeNode = TreeNode('A', [
TreeNode('B', [TreeNode('E')]),
TreeNode('C'),
TreeNode('D')
]);
接着,就是编写遍历树方法咯,分别为先根遍历和按层次遍历,如下:
TreeNode.prototype = {
constructor: TreeNode,
_traverseAsDFS: function(node){//先根遍历
var self = this;
if(node){
console.log(node.data);
node.children.forEach(function(child){
if(child.children.length){
self._traverseAsDFS(child);
}else{
console.log(child.data);
}
});
}
},
traverseAsDFS: function(){
console.log('Depth_First Search');
this._traverseAsDFS(this);
},
traverseAsBFS: function(){//按层次遍历
var queue = [];
console.log('Breadth_First Search');
console.log(this.data);
if(this.children.length){
queue.push(this);
}
while(queue.length){
let tempNode = queue.shift();
tempNode.children.forEach(function(child){
console.log(child.data);
if(child.children.length){
queue.push(child);
}
});
}
}
};
代码稍长,请自行打开
好了,利用上述二叉树例子,我们可以自行测试下:
var treeNode = TreeNode('A', [
TreeNode('B', [TreeNode('E')]),
TreeNode('C'),
TreeNode('D')
]);
treeNode.traverseAsDFS();//ABECD
treeNode.traverseAsBFS();//ABCDE
关于上述全部代码,见github。
树结构之JavaScript的更多相关文章
- 实现一个简单的虚拟DOM
现在的流行框架,无论React还是Vue,都采用虚拟DOM. 好处就是,当我们数据变化时,无需像Backbone那样整体重新渲染,而是局部刷新变化部分,如下组件模版: <ul class=&qu ...
- WEB前段(HTML+JS),后端(MYSQL+PHP)开发基础
一.HTML HTML:超文本标记语言,可以加载JS/CSS/图片/链接等非文字的内容 一切的网页开发技术都需要建立在HTML的基础之上 HTML的结构和语法 HTML元素 注释: <!-- ...
- JavaScript实现树结构(一)
JavaScript实现树结构(一) 一.树结构简介 1.1.简单了解树结构 什么是树? 真实的树: 树的特点: 树一般都有一个根,连接着根的是树干: 树干会发生分叉,形成许多树枝,树枝会继续分化成更 ...
- JavaScript实现树结构(二)
JavaScript实现树结构(二) 一.二叉搜索树的封装 二叉树搜索树的基本属性: 如图所示:二叉搜索树有四个最基本的属性:指向节点的根(root),节点中的键(key).左指针(right).右指 ...
- JavaScript遍历树结构
遍历 function parseTreeJson(treeNodes){ if(!treeNodes||!treeNodes.length)return; for(let i=0;i<tree ...
- 用JavaScript实现一个简单的树结构
数据源用数组混json结构,实现了基本的功能.效率一般,跟 dhtree 梅花雪树对比了下,都差不多. (ps感觉比dhtree快点,跟梅花雪树差不多,个人测试) 这个实现树的原理是根据json,不断 ...
- JavaScript 将行结构数据转化为树结构数据源(高效转化方案)
js接收到后台的数据如下 /// 部门信息 var departRows = [{ parentDepartId: 'root', departId: 'DC', departName: '集团' } ...
- react+redux教程(五)异步、单一state树结构、componentWillReceiveProps
今天,我们要讲解的是异步.单一state树结构.componentWillReceiveProps这三个知识点. 例子 这个例子是官方的例子,主要是从Reddit中请求新闻列表来显示,可以切换reac ...
- javascript性能优化-repaint和reflow
repaint(重绘) ,repaint发生更改时,元素的外观被改变,且在没有改变布局的情况下发生,如改变outline,visibility,background color,不会影响到dom结构渲 ...
随机推荐
- CTF-练习平台-Misc之 隐写2
二.隐写2 下载文件后解压,发现是一个png图片,依照老套路查看属性,没有发现 用WinHex打开,在图片文件中,修改图片宽度,将箭头处的A改为F,保存后打开图片 发现flag(对于png的文件格式详 ...
- log4net保存到数据库系列五、新增数据库字段
园子里面有很多关于log4net保存到数据库的帖子,但是要动手操作还是比较不易,从头开始学习log4net数据库日志一.WebConfig中配置log4net 一.WebConfig中配置log4ne ...
- 初探Net框架下的XML编程技术
一.前言: XML是微软.Net战略的一个重要组成部分,而且它可谓是XML Web服务的基石,所以掌握.Net框架下的XML技术自然显得非常重要了.本文将指导大家如何运用C#语言完成.Net框架下的X ...
- Yarn、MapReduce、spark、storm的关系
YARN并不是下一代 MapReduce (MRv2),下一代 MapReduce 与第一代 MapReduce (MRv1)在编程接口.数据处理引擎(MapTask和ReduceTask)是完全一样 ...
- Rockchip parameter文件详解
瑞芯微的安卓平台使用 parameter 文件来配置一些系统参数,比如定义串口号,固件版本,flash分区信息等. parameter 文件是由 BootLoader 解析的,大小不能超过 64 KB ...
- 【shell】grep命令
1.作用Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来.grep全称是Global Regular Expression Print,表示全局 ...
- 企业微信jssdk分享接口管理系统
服务项目 新手技术咨询 企业技术咨询 定制开发 服务说明 QQ有问必答 QQ.微信.电话 微信开发.php开发,网站开发,系统定制,小程序开发 价格说明 200元/月 1000/月 商议 ...
- 基于Hadoop开发网络云盘系统架构设计方案第一稿
引言 云计算技术的发展,各种网络云盘技术如雨后春笋,层出不穷,百度.新浪.网易都推出了自己的云盘系统,本文基于开源框架Hadoop设计实现了一套自己的网络云盘系统,方案为初步设计方案,不断完善中. 一 ...
- JsonCpp使用方法详解
JSON全称为JavaScript ObjectNotation,它是一种轻量级的数据交换格式,易于阅读.编写.解析.jsoncpp是c++解析JSON串常用的解析库之一. jsoncpp中主要的类: ...
- tcp端口检测
# coding=utf-8 import sys import socket import re def check_server(address, port): s = socket.socket ...