Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/420.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.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 如何一次创建一个项目的树数据结构?_Javascript_Arrays_Algorithm_Data Structures_Tree - Fatal编程技术网

Javascript 如何一次创建一个项目的树数据结构?

Javascript 如何一次创建一个项目的树数据结构?,javascript,arrays,algorithm,data-structures,tree,Javascript,Arrays,Algorithm,Data Structures,Tree,以下是此数据结构/算法的工作方式(每行1步): 您会注意到,在每个级别上,数字都位于树中的同一级别 在每一个级别上,每个数组在发生变化之前只能有3个项目 在从步骤4到步骤5的转换过程中,您会注意到,它必须将阵列向下嵌套一层 从步骤10到步骤11的转换也会进一步嵌套 模式将继续嵌套,因为每个级别获得3个项目 如步骤11所示,当您添加下一项时,它将添加到树的适当深度 所有数字(实际上是任意的“项目”)在树中处于相同的深度级别 棘手的部分是,当您到达特定运行的“末端”时,如何遍历阵列并将新阵列插入

以下是此数据结构/算法的工作方式(每行1步):

  • 您会注意到,在每个级别上,数字都位于树中的同一级别
  • 在每一个级别上,每个数组在发生变化之前只能有3个项目
  • 在从步骤4到步骤5的转换过程中,您会注意到,它必须将阵列向下嵌套一层
  • 从步骤10到步骤11的转换也会进一步嵌套
  • 模式将继续嵌套,因为每个级别获得3个项目
  • 如步骤11所示,当您添加下一项时,它将添加到树的适当深度
  • 所有数字(实际上是任意的“项目”)在树中处于相同的深度级别
棘手的部分是,当您到达特定运行的“末端”时,如何遍历阵列并将新阵列插入适当的位置?实现这一点的一般算法是什么?理想情况下,不是函数式算法,而是常规的过程式/命令式算法。我的尝试是失败的。本质上,这是在“树数组”中推送一个项目,使每个项目/对象/编号在树的叶子上保持相同的深度级别

当嵌套级别发生变化时,如何在树上来回移动以添加新项,这是我一直在努力解决的问题


注意:我用数字来说明它们的添加顺序。但是它们不应该在最终的算法中使用,它应该使用泛型对象。

您可以使用递归

首先递归到树中,始终选择最后一个条目,直到到达底部,这可以通过不再有子数组的事实来识别

然后,回溯阶段将用于构建一个新的子树,该子树最终将插入一个空闲点。起初,这个子树只是值本身。如果底层已经有空间,请在那里插入“子树”(实际上不是树)

但是如果没有空间,就让递归调用返回一个新值:它将是封装在数组中的值,所以像10变成了[10]。在调用函数中,我们是上一级的。如果有空间,则插入该值(在示例中为[10])。如果那里也没有空间,则再次包装该值并将其返回给调用者。在本例中,我们将返回[[10]]

因此,您不断地向上回溯递归树,并使值“更深”。在某些时候,它可以被插入,从那时起,函数将只返回
undefined
,以便向调用者指示作业已经完成,并且调用者也应该返回
undefined

在边界情况下,递归将回溯到原始调用方,而不插入值。在这种情况下,返回值将是仍然需要转到某个位置的包装值。因此,我们将整棵树加深,给它一个新根(这是添加的级别),其中原始根成为第一个子树,而包装的值成为第二个子树

下面是一个JavaScript实现:

类树{
构造函数(){
this.root=[];
}
增加(价值){
常量重复=(节点)=>{
if(Array.isArray(节点[0]){//尚未处于底层
value=recur(node[node.length-1]);//递归调用。。。
if(value==undefined)返回;//完成:退出递归
}
if(node.length==3)返回[value];//包装要插入的值
node.push(value);//这里有空间:插入(可能已包装)的值
//返回undefined表示该值已插入
};
值=重现(this.root);
//如果树已满,请增加树的深度
如果(value!==未定义)this.root=[this.root,value];
}
}
//演示
让树=新树;
for(设i=1;i<16;i++){
添加(i);
log(JSON.stringify(tree.root));

}
这里有一个稍微不同的迭代版本

不同之处在于,我们将节点插入到“正确”的位置,然后修复树。这比公认的解决方案效率稍低,但从学术角度来看可能很有趣

constadd=(树,节点)=>{
const parents=[];
让cur=树;
做{
父母。推(cur);
cur=cur[cur.length-1];
}while(Array.isArray(cur));
父项[parents.length-1]。推送(节点);
for(设idx=parents.length-1;idx>=1;idx-=1){
if(父项[idx]。长度==4){
父项[idx-1].push([parents[idx].pop()]);
}
}
if(tree.length==4){
树拼接(0,4,树切片(0,3),[tree[3]];
}
};
常量myTree=[];
for(设id=1;id[1]
// => [1,2]
// => [1,2,3]
// => [[1,2,3],[4]]
// => [[1,2,3],[4,5]]
// => [[1,2,3],[4,5,6]]
// => [[1,2,3],[4,5,6],[7]]
// => [[1,2,3],[4,5,6],[7,8]]
// => [[1,2,3],[4,5,6],[7,8,9]]
// => [[[1,2,3],[4,5,6],[7,8,9]],[[10]]]
// => [[[1,2,3],[4,5,6],[7,8,9]],[[10,11]]]
// => [[[1,2,3],[4,5,6],[7,8,9]],[[10,11,12]]]
// => [[[1,2,3],[4,5,6],[7,8,9]],[[10,11,12],[13]]]
// => [[[1,2,3],[4,5,6],[7,8,9]],[[10,11,12],[13,14]]]
// => [[[1,2,3],[4,5,6],[7,8,9]],[[10,11,12],[13,14,15]]]
//=>[[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15],[16]]

。作为控制台包装器{max height:100%!important;top:0}
我想我有点困惑,因为
被重新分配了,这些应该是不同的不相关变量吗?如果你希望不同的变量,请继续,但我更喜欢这样,因为否则,您必须区分底层插入和其他插入。它当然可以不递归地完成。试试看;-)你能做到没有内联函数吗?想弄明白,但也许你能做得更快
 1. []
 2. [1]
 3. [1, 2]
 4. [1, 2, 3]
 5. [[1, 2, 3], [4]]
 6. [[1, 2, 3], [4, 5]]
 7. [[1, 2, 3], [4, 5, 6]]
 8. [[1, 2, 3], [4, 5, 6], [7]]
 9. [[1, 2, 3], [4, 5, 6], [7, 8]]
10. [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
11. [[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[10]]]
12. [[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[10, 11]]]
13. [[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[10, 11, 12]]]
14. [[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[10, 11, 12], [13]]]
15. [[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[10, 11, 12], [13, 14]]]
16. [[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[10, 11, 12], [13, 14, 15]]]...