树结构之JavaScript


Posted in Javascript onJanuary 24, 2017

对于数据结构“树”,想必大家都熟悉,今儿,我们就再来回顾一下数据结构中的二叉树与树,并用JavaScript实现它们。

ps:树结构在前端中,很多地方体现得淋漓尽致,如Vue的虚拟DOM以及冒泡等等。

二叉树

--概念--

二叉树是一种树形结构,它的特点是每个结点至多只有两棵子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能任意颠倒。

如下,就是一棵二叉树(注:下文二叉树相关例子,都以该二叉树为例):

树结构之JavaScript

且,遍历二叉树(traversing binary tree)有三种常用方式,如下:

1)、先序遍历二叉树 (根左右)  

        若二叉树为空,则空操作;否则

        --访问根结点;

        --先序遍历左子树;

        --先序遍历右子树。

例如,上述例子中的二叉树,遍历结果如下:

树结构之JavaScript

2)、中序遍历二叉树(左根右)

         若二叉树为空,则空操作;否则

         --中序遍历左子树;

         --访问根结点;

         --中序遍历右子树。

例如,上述例子中的二叉树,遍历结果如下:

树结构之JavaScript

3)、后序遍历二叉树(左右根)

        若二叉树为空,则空操作;否则

        --后序遍历左子树;

        --后序遍历右子树;

--访问根结点。

例如,上述例子中的二叉树,遍历结果如下:

树结构之JavaScript

好了,了解了二叉树以及遍历方式,那么,接下来我们就一起用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)个互不相交的有限集,其中每个集合本身又是一棵树,称为根的子树。当然,二叉树肯定属于树咯。

如下,就是一棵树(注:下文树的相关例子,都以该树为例):

树结构之JavaScript

,遍历一棵多孩子树,有两种常用遍历方式,如下:

1) 、先根遍历,和深度优先搜索(Depth_First Search)遍历类似。都是利用栈来遍历元素,如下:

树结构之JavaScript

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

树结构之JavaScript

好了,了解了树以及遍历方式,那么,接下来我们就一起用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 相关文章推荐
js下用eval生成JSON对象
Sep 17 Javascript
关于Mozilla浏览器不支持innerText的解决办法
Jan 01 Javascript
jquery键盘事件使用介绍
Nov 01 Javascript
情人节之礼 js项链效果
Feb 13 Javascript
回车直接实现点击某按钮的效果即触发单击事件
Feb 27 Javascript
PHP PDO操作总结
Nov 17 Javascript
AngularJS入门教程之Select(选择框)详解
Jul 27 Javascript
js修改onclick动作的四种方法(推荐)
Aug 18 Javascript
Select2.js下拉框使用小结
Oct 24 Javascript
vue2.0 computed 计算list循环后累加值的实例
Mar 07 Javascript
ng-alain表单使用方式详解
Jul 10 Javascript
关于vue.js中实现方法内某些代码延时执行
Nov 14 Javascript
AngularJS实现使用路由切换视图的方法
Jan 24 #Javascript
javascript 正则表达式去空行方法
Jan 24 #Javascript
JavaScript中动态向表格添加数据
Jan 24 #Javascript
微信小程序开发的四十个技术窍门总结(推荐)
Jan 23 #Javascript
ajax分页效果(bootstrap模态框)
Jan 23 #Javascript
jquery easyui DataGrid简单示例
Jan 23 #Javascript
浅谈javascript的闭包
Jan 23 #Javascript
You might like
屏蔽浏览器缓存另类方法
2006/10/09 PHP
php 伪造本地文件包含漏洞的代码
2011/11/03 PHP
php中的boolean(布尔)类型详解
2013/10/28 PHP
浅谈php命令行用法
2015/02/04 PHP
Yii2实现ajax上传图片插件用法
2016/04/28 PHP
PHP简单获取网站百度搜索和搜狗搜索收录量的方法
2016/08/23 PHP
详解PHP防止直接访问.php 文件的实现方法
2017/07/28 PHP
JQuery 弹出框定位实现方法
2010/12/02 Javascript
理解和运用JavaScript的闭包机制
2015/08/13 Javascript
jquery中live()方法和bind()方法区别分析
2016/06/23 Javascript
js智能获取浏览器版本UA信息的方法
2016/08/08 Javascript
vue.js将unix时间戳转换为自定义时间格式
2017/01/03 Javascript
浅谈jQuery中的$.extend方法来扩展JSON对象
2017/02/12 Javascript
jqueryUI tab标签页代码分享
2017/10/09 jQuery
通过 JS 判断页面是否有滚动条的实现方法
2018/04/05 Javascript
浅析vue给不同环境配置不同打包命令
2018/08/17 Javascript
Vue动态创建注册component的实例代码
2019/06/14 Javascript
详解基于Vue/React项目的移动端适配方案
2019/08/23 Javascript
[03:36]2014DOTA2 TI小组赛综述 八强诞生进军钥匙球馆
2014/07/15 DOTA
Python利用QQ邮箱发送邮件的实现方法(分享)
2017/06/09 Python
Python 将pdf转成图片的方法
2018/04/23 Python
Python3爬虫之urllib携带cookie爬取网页的方法
2018/12/28 Python
python3.4 将16进制转成字符串的实例
2019/06/12 Python
Django中如何使用sass的方法步骤
2019/07/09 Python
python 日期排序的实例代码
2019/07/11 Python
Python 创建TCP服务器的方法
2020/07/28 Python
美国精品地毯网站:Boutique Rugs
2020/03/04 全球购物
上海奥佳笔试题面试题
2016/11/16 面试题
2019年.net常见面试问题
2012/02/12 面试题
城市轨道交通工程职业规划书范文
2014/01/18 职场文书
大学班级计划书
2014/04/29 职场文书
关于环保的建议书
2014/05/12 职场文书
学校党委干部个人对照检查材料思想汇报
2014/10/09 职场文书
2014年政协委员工作总结
2014/12/01 职场文书
2015年董事长秘书工作总结
2015/07/23 职场文书
在HTML中引入CSS的几种方式介绍
2021/12/06 HTML / CSS