对于数据结构“树”,想必大家都熟悉,今儿,我们就再来回顾一下数据结构中的二叉树与树,并用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的更多相关文章

  1. 实现一个简单的虚拟DOM

    现在的流行框架,无论React还是Vue,都采用虚拟DOM. 好处就是,当我们数据变化时,无需像Backbone那样整体重新渲染,而是局部刷新变化部分,如下组件模版: <ul class=&qu ...

  2. WEB前段(HTML+JS),后端(MYSQL+PHP)开发基础

    一.HTML HTML:超文本标记语言,可以加载JS/CSS/图片/链接等非文字的内容 一切的网页开发技术都需要建立在HTML的基础之上 HTML的结构和语法 HTML元素 注释:  <!-- ...

  3. JavaScript实现树结构(一)

    JavaScript实现树结构(一) 一.树结构简介 1.1.简单了解树结构 什么是树? 真实的树: 树的特点: 树一般都有一个根,连接着根的是树干: 树干会发生分叉,形成许多树枝,树枝会继续分化成更 ...

  4. JavaScript实现树结构(二)

    JavaScript实现树结构(二) 一.二叉搜索树的封装 二叉树搜索树的基本属性: 如图所示:二叉搜索树有四个最基本的属性:指向节点的根(root),节点中的键(key).左指针(right).右指 ...

  5. JavaScript遍历树结构

    遍历 function parseTreeJson(treeNodes){ if(!treeNodes||!treeNodes.length)return; for(let i=0;i<tree ...

  6. 用JavaScript实现一个简单的树结构

    数据源用数组混json结构,实现了基本的功能.效率一般,跟 dhtree 梅花雪树对比了下,都差不多. (ps感觉比dhtree快点,跟梅花雪树差不多,个人测试) 这个实现树的原理是根据json,不断 ...

  7. JavaScript 将行结构数据转化为树结构数据源(高效转化方案)

    js接收到后台的数据如下 /// 部门信息 var departRows = [{ parentDepartId: 'root', departId: 'DC', departName: '集团' } ...

  8. react+redux教程(五)异步、单一state树结构、componentWillReceiveProps

    今天,我们要讲解的是异步.单一state树结构.componentWillReceiveProps这三个知识点. 例子 这个例子是官方的例子,主要是从Reddit中请求新闻列表来显示,可以切换reac ...

  9. javascript性能优化-repaint和reflow

    repaint(重绘) ,repaint发生更改时,元素的外观被改变,且在没有改变布局的情况下发生,如改变outline,visibility,background color,不会影响到dom结构渲 ...

随机推荐

  1. HDU 4662 MU Puzzle 数论或者水题

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4662 题目是问目标串能否由MI得到,我们可以逆向思维,目标串能否反过来处理得到MI,所以,首先排除M ...

  2. 《DSP using MATLAB》Problem 3.17

    用差分方程两边进行z变换,再变量带换得到频率响应函数(或转移函数,即LTI系统脉冲响应的DTFT). 代码: %% ------------------------------------------ ...

  3. hdu2067 小兔的棋盘 DP/数学/卡特兰数

    棋盘的一角走到另一角并且不越过对角线,卡特兰数,数据量小,可以当做dp求路径数 #include<stdio.h> ][]; int main() { ; ) { int i,j; lon ...

  4. HDU2476 String painter

    题意 String painter Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  5. web页面的数据从excel中读取

    # -*- coding: utf-8 -*- import xdrlib ,sysimport xlrdimport datetimeimport jsonimport conf,reimport ...

  6. day12 python学习 装饰器

    闭包函数: 内部函数包含对外部作用域而非全剧作用域名字的引用,该内部函数称为闭包函数#函数内部定义的函数称为内部函数 闭包函数获取网络应用 from urllib.request import url ...

  7. stenciljs ionic 团队开发的方便web 组件框架

    stenciljs 是ionic 团队开发的方便组件话开发的js 框架,具体以下特点 简单,零配置,简单的api,typescript 支持 性能,压缩之后6Kb,支持ssr,以及强大的原生web c ...

  8. 转 update关联更新在sqlserver和oracle中的实现

    sqlserver和oracle中实现update关联更新的语法不同,都可以通过inline view(内嵌视图)来实现,总的来说sqlserver更简单些. 测试例子如下: create table ...

  9. html 滚动固定显示js脚本

    <script type="text/javascript">function htmlScroll(){ var top = document.body.scroll ...

  10. mysql和redis加入到windows服务

    mysql加入到windows服务: mysqld --install  Mysql5.6 mysqld --remove mysql5.6  从windows的服务中删除mysql服务 net st ...