对于数据结构“树”,想必大家都熟悉,今儿,我们就再来回顾一下数据结构中的二叉树与树,并用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. CTF-练习平台-Misc之 隐写2

    二.隐写2 下载文件后解压,发现是一个png图片,依照老套路查看属性,没有发现 用WinHex打开,在图片文件中,修改图片宽度,将箭头处的A改为F,保存后打开图片 发现flag(对于png的文件格式详 ...

  2. log4net保存到数据库系列五、新增数据库字段

    园子里面有很多关于log4net保存到数据库的帖子,但是要动手操作还是比较不易,从头开始学习log4net数据库日志一.WebConfig中配置log4net 一.WebConfig中配置log4ne ...

  3. 初探Net框架下的XML编程技术

    一.前言: XML是微软.Net战略的一个重要组成部分,而且它可谓是XML Web服务的基石,所以掌握.Net框架下的XML技术自然显得非常重要了.本文将指导大家如何运用C#语言完成.Net框架下的X ...

  4. Yarn、MapReduce、spark、storm的关系

    YARN并不是下一代 MapReduce (MRv2),下一代 MapReduce 与第一代 MapReduce (MRv1)在编程接口.数据处理引擎(MapTask和ReduceTask)是完全一样 ...

  5. Rockchip parameter文件详解

    瑞芯微的安卓平台使用 parameter 文件来配置一些系统参数,比如定义串口号,固件版本,flash分区信息等. parameter 文件是由 BootLoader 解析的,大小不能超过 64 KB ...

  6. 【shell】grep命令

    1.作用Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来.grep全称是Global Regular Expression Print,表示全局 ...

  7. 企业微信jssdk分享接口管理系统

    服务项目 新手技术咨询 企业技术咨询 定制开发 服务说明 QQ有问必答 QQ.微信.电话 微信开发.php开发,网站开发,系统定制,小程序开发 价格说明 200元/月 1000/月 商议       ...

  8. 基于Hadoop开发网络云盘系统架构设计方案第一稿

    引言 云计算技术的发展,各种网络云盘技术如雨后春笋,层出不穷,百度.新浪.网易都推出了自己的云盘系统,本文基于开源框架Hadoop设计实现了一套自己的网络云盘系统,方案为初步设计方案,不断完善中. 一 ...

  9. JsonCpp使用方法详解

    JSON全称为JavaScript ObjectNotation,它是一种轻量级的数据交换格式,易于阅读.编写.解析.jsoncpp是c++解析JSON串常用的解析库之一. jsoncpp中主要的类: ...

  10. tcp端口检测

    # coding=utf-8 import sys import socket import re def check_server(address, port): s = socket.socket ...