Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在JavaScript中递归遍历通用树(不是BST)?_Javascript_Algorithm_Recursion_Data Structures_Tree - Fatal编程技术网

如何在JavaScript中递归遍历通用树(不是BST)?

如何在JavaScript中递归遍历通用树(不是BST)?,javascript,algorithm,recursion,data-structures,tree,Javascript,Algorithm,Recursion,Data Structures,Tree,假设我们想对公司中存在的去层级结构进行建模。最基本的数据结构称为employee。每个员工都是自己的对象/树,有两个属性:级别是一个整数,报告是一个包含0个或更多员工的对象/树 我们可以说employee数据结构如下所示: { employee: { level: Number, reports: Object //Contains 0 to N employees } } { boss: { level: 0, reports: {

假设我们想对公司中存在的去层级结构进行建模。最基本的数据结构称为
employee
。每个
员工
都是自己的对象/树,有两个属性:
级别
是一个整数,
报告
是一个包含0个或更多
员工的对象/树

我们可以说
employee
数据结构如下所示:

{
    employee: {
        level: Number,
        reports: Object //Contains 0 to N employees
    }
}
{
boss: {
  level: 0,
  reports: {
    employee0: {
      level: 1,
      reports: {
        anotherEmployee0: {
          level: 2,
          reports: { /* ... */ },
        },
        anotherEmployee0: {
          level: 2,
          reports: { /* ... */ },
        },
      },
    },
    employee1: {
      level: 1,
      reports: { /* ... */ },
    },
  },
},
};
小型企业可以代表其组织如下:

{
    employee: {
        level: Number,
        reports: Object //Contains 0 to N employees
    }
}
{
boss: {
  level: 0,
  reports: {
    employee0: {
      level: 1,
      reports: {
        anotherEmployee0: {
          level: 2,
          reports: { /* ... */ },
        },
        anotherEmployee0: {
          level: 2,
          reports: { /* ... */ },
        },
      },
    },
    employee1: {
      level: 1,
      reports: { /* ... */ },
    },
  },
},
};

我们如何使用递归遍历这个结构?理想情况下,这样做不需要语言函数抽象,例如,
for。。。在
foreach
map
。所以,“用手”。我希望看到两种解决方案(有和没有上述抽象)进行比较。

for..in
是一种核心语言结构,从一开始就是JavaScript语言的一部分。这是提供的第一种检查对象属性的方法

我在这里提供两种解决方案。第一个将坚持您的数据结构,并将使用
for..in
读取给定对象的属性,并对
报告
值执行条件递归。它调用用户提供的回调函数,因此用户可以决定如何处理迭代值

第二种方法切换到更好的数据结构,因为最好不使用对象属性名称来表示动态内容。相反,将属性添加到对象(可能是“名称”)中,并将动态内容指定给该对象(“employee1”、“boss”等)。它将函数定义为生成器,而不是老式的回调系统

解决方案1(
for..in
+回调): 这是ES3兼容的

函数遍历(组织、回调、父级){
for(组织中的变量名称){
var obj=组织[名称];
回调(名称、对象级别、父级);
如果(目标报告){
遍历(对象报告、回调、名称);
}
}
}
//使用原始数据结构演示
var org={boss:{level:0,reports:{employee0:{level:1,reports:{anotherEmployee0:{level:2,reports:{/*.*/},reports:{/*.*/},},},reports:{anotherEmployee1:{level 1,reports:{/*.*.*/},},},},};
遍历(组织、访问、空);
//处理迭代值的函数:
功能访问(名称、级别、父级){
console.log(“.slice(0,level)+name+”(“+”level“+level+”)在“+(parent | | |“no one”)下);

}
Trincot的出色回答使用了生成器“而不是老式的回调系统”

下面是使用trincot对输入数据的重组来演示老式系统的工作原理:

const traverseOrg=(fn)=>(org,boss=null)=>
org.forEach(emp=>{
fn(emp、boss)
特拉维斯堡(fn)(emp.reports | | |[],emp)
})
让org2=[{name:“boss”,级别:0,报告:[{name:“employee0”,级别:1,报告:[{name:“anotherEmployee0”,级别:2,报告:[/*…*/]},{name:“anotherEmployee1”,级别:2,报告:[/*…*/]},{name:“employee1”,级别:1,报告:[/*…*/]}];
特拉维斯堡(
({level,name},boss)=>console.log(
`${'。重复(级别)}${name}(级别${level})报告给${boss?boss.name:“没有人”}`
)

)(org2)
“语言函数抽象”:我从未听说过这个短语。那是什么?在中,
的问题是什么?它从一开始就属于语言的核心。“手动”:您的意思是它应该在ES3中,而不是在更高版本中吗?请添加您的try。@trincot如果您使用的是ES6内置函数,您使用的是抽象逻辑而不是实现,不是吗
foreach
封装了您没有编写的逻辑,不是抽象的吗?我们能称之为抽象吗?抱歉,如果这不是一个实际的术语,但这就是我的意思。@NinaScholz是的,正在研究它。我只是被卡住了,一直在练习使用二叉树,但我注意到我的组织不能表示为二叉树P@trincot哦,对不起,我忘了回答其余的问题。我对。。。在
或其他方面,它们当然很有用,但我想学习如何在较低级别上操作数据结构,以及如何解决您需要自己处理的问题。它们提供了抽象,我想自己操作它们。谢谢你的解决方案,也谢谢你带我走过它们。如上所述,如果问题不清楚或有缺陷,我表示歉意。我还感谢您对数据结构本身、存在的问题以及提供更好的替代方案的评论。出于某种原因,我希望能够使用递归和no
For
循环来迭代、循环整个结构。很明显,我还有很多东西要学!很抱歉发布了令人沮丧和困惑的问题!哈哈,但我很高兴你仍然提供了一个解决方案。我希望你明白,在这个平台上的交流有时是枯燥和直接的。别把它当回事。我们都对编码有着共同的爱好。继续努力。