Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/449.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_Algorithm_Data Structures_Tree_Logic - Fatal编程技术网

使用JavaScript生成随机树

使用JavaScript生成随机树,javascript,algorithm,data-structures,tree,logic,Javascript,Algorithm,Data Structures,Tree,Logic,我正在做一个项目,生成随机数据结构,用于测试DSA问题的解决方案。我试图形成一个算法,生成一个随机树数据结构,该结构接受测试用例数和节点数的输入。因为我不能使用指针和引用,所以我很难弄清楚如何在javaScript中做到这一点 到目前为止,我成功地掌握了基本知识,但是,我的代码中出现了错误 代码: const randnumgen=(最小值,最大值)=>{ min=数学单元(min); 最大值=数学楼层(最大值); 返回Math.floor(Math.random()*(max-min+1))

我正在做一个项目,生成随机数据结构,用于测试DSA问题的解决方案。我试图形成一个算法,生成一个随机树数据结构,该结构接受测试用例数和节点数的输入。因为我不能使用指针和引用,所以我很难弄清楚如何在javaScript中做到这一点

到目前为止,我成功地掌握了基本知识,但是,我的代码中出现了错误

代码:
const randnumgen=(最小值,最大值)=>{
min=数学单元(min);
最大值=数学楼层(最大值);
返回Math.floor(Math.random()*(max-min+1))+min;
};
函数randtreegen(节点){
var字符串=”;
类树{
构造函数(节点){
this.nodes=节点;
this.adj=[];
}
附录(北、西){
this.adj[n].push(w);
}
移除(北,西){
this.adj[n].forEach((elem)=>{
如果(元素===w){
var index=this.adj[n].indexOf(elem);
如果(索引!=-1)这个.adj[n]。拼接(索引,1);
}
});
}
isCyclicUtil(节点、已访问、recStack){
if(已访问的[节点]==false){
访问的[节点]=真;
recStack[nodes]=true;
this.adj[n].forEach((elem)=>{
if(!visted[elem]&&this.isCyclicUtil(elem,visted,recStack))
返回true;
else if(recStack[elem])
返回true;
});
}
recStack[nodes]=false;
返回false;
}
isCyclic(){
已访问=新数组();
recStack=新数组();
对于(var i=0;i{
字符串+=元素+'\n'
});
返回字符串;
}
功能树(测试用例、树节点){
var结果=”;
而(测试用例-->0){
结果+=randtreegen(树节点)+'\n';
}
返回结果;
}
常数ans=treeGen(1,5);

文件编写(ans)主要问题是您没有将
adj
条目创建为空数组。因此,改变:

  this.adj = [];
致:

但还有其他问题:

  • 一些代码要求节点从1开始编号,而其他代码要求从0开始编号。由于数组索引从0开始,所以更自然的做法是从0开始为节点编号

  • 存在对未知变量
    n
    的引用,该变量应为
    节点
    。注意:奇怪的是,您为这个变量选择了复数名称

  • 当您在
    forEach
    回调中
    返回true
    时,您不会从外部函数返回,而只能从
    forEach
    回调返回。这不是你想要的。通过使用
    for…of
    循环解决此问题

  • isCyclic
    中,在
    j
    上有一个循环,但是随着
    i++
    的增加,这个循环永远不会结束。让它成为
    j++

  • 循环测试不足以确保图形是树,因为在有向图中,节点a和节点B之间仍然可以有多条路径,而没有循环

  • 创建边的循环还需要一次迭代,所以让它从0开始

不过,我建议使用一种稍有不同的方法来生成随机树:随机洗牌所有节点,并让洗牌数组中的第一个节点成为树的根。迭代所有其他节点,让它们成为新边的目标。请注意,在树中没有两条边到达的节点

然后你可以做一个循环测试。不过,我也会这样做:在添加边缘之前执行测试。您可以获取所选
b
节点的所有子节点,如果
a
在该集中,则不应创建边
a,b

这是你的代码。我移除了不再使用的部件:

函数随机数(最小值、最大值){
min=数学单元(min);
最大值=数学楼层(最大值);
返回Math.floor(Math.random()*(max-min+1))+min;
}
类树{
构造函数(节点){
this.nodes=节点;
this.adj=Array.from({length:nodes},()=>[]);
}
附录(北、西){
this.adj[n].push(w);
}
子体(节点){
let visited=新集合([node]);
for(让已访问的节点){
for(设此.adj[node]的元素){
如果(!visted.has(elem))已访问,则添加(elem);
}
}
回访;
}
}
函数洗牌(数组){
对于(var i=array.length-1;i>0;i--){
var j=Math.floor(Math.random()*(i+1));
var-temp=数组[i];
数组[i]=数组[j];
数组[j]=温度;
}
返回数组;
}
函数randtreegen(节点){
设t=新树(节点);
让[root,…children]=shuffle([…数组(节点).keys());
设边=[];
让我们一起来;
为了(让b为儿童){
做{
a=randnumgen(0,nodes-1);//以零为基础
}而(t.b.has(a));
t、 增编(a、b);
边缘。推动([a,b]);
}
返回边。连接(“\n”);
}
功能树(测试用例、树节点){
var结果=”;
而(测试用例-->0){
结果+=randtreegen(树节点)+'\n';
  this.adj = Array.from({length: nodes}, () => []); // create that many empty arrays