本文主要介绍了javascript数据结构中多树的经典操作,简述了多树的概念,并结合实例分析了javascript中多树的创建、添加、遍历、删除等常见操作方法。有需要的可以参考一下。
本文结合实例介绍了javascript数据结构中多树的经典操作。分享给你,供你参考,如下:
多树可以实现复杂数据结构的存储,通过遍历的方法查找数据方便高效,提高了查找的效率,方便了节点数据的管理。javascript的DOM实际上是以多树形式存储的。下面的javascript用于实现多树的数据结构
1、创造一个节点
数据以节点的形式存储:
类节点{
构造函数(数据){
this.data=data
this.parent=null
this . children=[];
}
}
2、创造树
树是用来连接节点的,就像现实世界树的树干一样,有很多分支。
类别多路树{
构造函数(){
这个。_ root=null
}
}
3、添加一个节点
函数add(data,toData,traversal) {
let node=新节点(数据)
//第一次添加到根节点
//返回值是这个,方便在chain中添加节点。
如果(这个。_root===null) {
这个。_ root=node
还这个;
}
设parent=null,
回调=函数(节点){
if (node.data===toData) {
父=节点;
返回true
}
};
//根据遍历方法(遍历方法后面会讨论)找到父节点,然后将节点添加到父节点。
//在子数组中
//搜索方法包含的内容将在后面讨论。
this.contains(回调,遍历);
如果(父项){
parent.children.push(节点);
node.parent=parent
还这个;
}否则{
抛出新错误(“无法将节点添加到不存在的父节点中。”);
}
}
4、深度优先遍历
深度优先会先尝试从子节点开始搜索,搜索完子节点后再从兄弟节点开始搜索,适用于数据深度较大的情况,比如文件目录。
函数traverseDF(回调){
设stack=[],found=false
stack.unshift(this。_ root);
let current node=stack . shift();
而(!找到当前节点){
//根据回调函数的返回值决定找到第一个后是否继续搜索。
found=callback(current node)==true?真:假;
如果(!找到){
//每次把子节点放在栈顶,下一次搜索都会先找到子节点。
stack.unshift(.current node . children);
current node=stack . shift();
}
}
}
5、广度优先遍历
广度优先遍历会优先寻找兄弟节点,一层一层往下,适用于子项较多的情况,比如公司岗位级别。
函数traverseBF(回调){
let queue=[],found=false
queue.push(这个。_ root);
let current node=queue . shift();
而(!找到当前节点){
//根据回调函数的返回值决定找到第一个后是否继续搜索。
found=callback(current node)==true?真:假;
如果(!找到){
//每次将子节点放在队列末尾时,在下一次搜索中将首先找到同级节点。
队列.推送(.currentNode.children)
current node=queue . shift();
}
}
}
6、包含节点
函数包含(回调,遍历){
traversal.call(this,回调);
}
函数回调算法可以根据情况自行实现,灵活性高。
7、移除节点
//返回移除的节点
函数remove(data,fromData,traversal) {
设parent=null,
childToRemove=null,
回调=函数(节点){
if (node.data===fromData) {
父=节点;
返回true
}
};
this.contains(回调,遍历);
如果(父项){
让index=this。_findIndex(parent.children,data);
如果(索引0) {
引发新错误(“要移除的节点不存在。”);
}否则{
childToRemove=parent . children . splice(index,1);
}
}否则{
抛出新错误(“父级不存在。”);
}
返回childToRemove
}
_findIndex实现:
function _findIndex(arr,data) {
设index=-1;
for(设i=0,len=arr.length我leni ) {
if (arr[i]).数据===数据){
index=I;
打破;
}
}
回报指数;
}
完整算法
类节点{
构造函数(数据){
this.data=数据
this.parent=null
这个。children=[];
}
}
类别多路树{
构造函数(){
这个. root=null
}
//深度优先遍历
traverseDF(回调){
设堆栈=[],发现=假
stack.unshift(this ._ root);
让当前节点=堆栈。shift();
而(!找到当前节点){
found=callback(当前节点)==true?真:假;
如果(!找到){
stack.unshift(.当前节点。儿童);
当前节点=堆栈。shift();
}
}
}
//广度优先遍历
traverseBF(回调){
假设队列=[],发现=假
队列.推送(这个. root);
让当前节点=队列。shift();
而(!找到当前节点){
found=callback(当前节点)==true?真:假;
如果(!找到){
队列。推送(.currentNode.children)
当前节点=队列。shift();
}
}
}
包含(回调,遍历){
traversal.call(这个,回调);
}
添加(数据,toData,遍历){
让节点=新节点(数据)
如果(这个. root===null) {
这个. root=node
还这个;
}
设parent=null,
回调=函数(节点){
if (node.data===toData) {
父=节点;
返回真实的
}
};
这包含(回调,遍历);
如果(父项){
parent.children.push节点);
node.parent=parent
还这个;
}否则{
抛出新错误("无法将节点添加到不存在的父节点中。");
}
}
remove(data,fromData,traversal) {
设parent=null,
childToRemove=null,
回调=函数(节点){
if (node.data===fromData) {
父=节点;
返回真实的
}
};
这包含(回调,遍历);
如果(父项){
让索引=this ._findIndex(parent.children,data);
如果(索引0) {
引发新错误("要移除的节点不存在。");
}否则{
childToRemove=parent。孩子。拼接(索引,1);
}
}否则{
抛出新错误("父级不存在。");
}
返回childToRemove
}
_findIndex(arr,data) {
设index=-1;
对于(设i=0,len=数组长度我leni ) {
if (arr[i]).数据===数据){
index=I;
打破;
}
}
回报指数;
}
}
控制台测试代码
var tree=new multi hytree();
tree.add('a ')。add('b ',' a ',tree.traverseBF)。add('c ',' a ',tree.traverseBF)。add('d ',' a ',tree.traverseBF)。add('e ',' b ',tree.traverseBF)。add('f ',' b ',tree.traverseBF)。add('g ',' c ',tree.traverseBF)。add('h ',' c ',tree.traverseBF)。添加(' I ',' d ',树。遍历BF);
控制台。组('遍历df ');
tree.traverseDF(函数(节点){
控制台。日志(节点。数据);
});
控制台。groupend(' traverse df ');
控制台。组('遍历BF ');
树。遍历BF(函数(节点){
控制台。日志(节点。数据);
});
控制台。groupend('遍历BF ');
//深度优先查找
控制台。组(“包含1”);
树.包含(函数(节点){
控制台。日志(节点。数据);
if (node.data==='f') {
返回真实的
}
}、树。遍历df);
console.groupEnd('contains1 ')
//广度优先查找
控制台。组(“包含2”);
树.包含(函数(节点){
控制台。日志(节点。数据);
if (node.data==='f') {
返回真实的
}
},树。遍历BF);
控制台。groupend(“包含2”);
tree.remove('g ',' c ',tree。遍历BF);
这里使用在线HTML/CSS/JavaScript代码运行工具:http://工具。jb51。net/code/html jsrun测试运行效果如下:
感兴趣的朋友可以自己测试一下看看运行效果。
更多关于Java脚本语言相关内容感兴趣的读者可查看本站专题: 《JavaScript数据结构与算法技巧总结》 、 《JavaScript数学运算用法总结》 、 《JavaScript排序算法总结》 、 《JavaScript遍历算法与技巧总结》 、 《JavaScript查找算法技巧总结》 及《JavaScript错误与调试技巧总结》
希望本文所述对大家Java脚本语言程序设计有所帮助。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。