如何解决Javascript - 遍历一棵树以生成节点的序列
我发现很少有与此相关的 SO 问题,但没有一个是基于我试图解决的确切问题。
目标是生成一个序列字符串,该字符串将提供顺序遍历整个树的路径。
例如下图的输出应该是123242523637321
如您所见,树从节点 1 开始,然后到达节点 2。
节点 2 连接到其他 3 个节点,即。节点 3、节点 4 和节点 5。
按照顺序,下一个节点是3。
要转到下一个节点,即节点 4,我们必须返回节点 2,然后再转到节点 4,因此字符串变为 12324
一旦我们得到最后一个节点,即节点 7,我们将返回到第一个节点,因此字符串以子字符串 7321
结束上图的示例树结构是 -
const sequenceObj = {
1: {
id: "Point_1cec2262-20f8-4985-adcb-b6d95a618d22",connectednodes: ["2"]
},2: {
id: "Point_02bdae16-1cdb-48e1-a601-7b1e526eedb8",connectednodes: ["1","3","4","5"]
},3: {
id: "Point_55a68ac0-17ef-48a2-bf9f-c70004a27d99",connectednodes: ["2","6","7"]
},4: {
id: "Point_8760427c-98bb-4e3e-85dd-59cba3b31c6f",5: {
id: "Point_79a7bcec-d110-43dc-b9ac-1552538bc1a5",6: {
id: "Point_37550cf0-4bd5-48b2-b32f-9018bd55c05f",connectednodes: ["3"]
},7: {
id: "Point_2de67998-9e1f-4b06-af18-77d558d68254",connectednodes: ["3"]
}
};
如您所见,每个节点都有一个名为 connectednodes 的属性,可帮助我们遍历树。
编辑 - 正如评论中所指出的,属性 connectednodes(以前称为 children)存储连接节点的 id。 提供的对象不代表树,我们只需要使用这个对象从头到尾遍历,即在这个例子中从id 1到7。
如果我遗漏了什么或需要更多信息,请告诉我。
谢谢!
解决方法
您的输入写在一个节点中,将它们的父节点列为 export const RegisterWithEmail = async user => {
console.log("Called Once...");
if(!user) return 'SOMETHING_WENT_WRONG';
else {
const snap = await firestore.collection('users').where('email','==',user.email).get();
const docs = snap.docs.map((doc) => doc.data());
if (docs.length !== 0) return 'EMAIL_HAS_ALREADY_BEEN_TAKEN';
try {
console.log("Trying to register email...");
return await auth.createUserWithEmailAndPassword(user.email,user.password).then(async usr => {
await usr.user.updateProfile({
displayName: user.name
}) // SETTING NAME
const sendVerifyEmail = usr.user.sendEmailVerification().then(() => setTimer(usr.user,5))
return await sendVerifyEmail.then(msg => {
console.log('Finishing...',msg)
if(msg.txt !== 'waiting') {
if(msg.error) {
throw msg.txt
}
else return msg.txt
}
}).catch(() => {
throw 'EMAIL_NOT_SENT'
})
}).catch(() => {
throw 'USER_NOT_CREATED'
})
} catch (err) {
throw 'USER_ALREADY_REGISTERED'
}
}
}
。我们先解决这个问题 -
children
现在我们可以编写您的 const node = (id,...children) =>
({ constructor: node,id,children })
const tree =
node(1,node(2,node(3,node(7),node(6)),node(4),node(5)))
-
traverse
function* traverse(t)
{ switch (t?.constructor)
{ case node:
yield t.id
for (const c of t.children)
{ yield *traverse(c)
yield t.id
}
}
}
for (const v of traverse(tree))
console.log(v)
或者我们可以将它们全部收集在一个字符串中
1
2
3
7
3
6
3
2
4
2
5
2
1
展开下面的代码片段以在您自己的浏览器中验证结果 -
console.log(Array.from(traverse(tree)).join(""))
const node = (id,children })
function* traverse(t)
{ switch (t?.constructor)
{ case node:
yield t.id
for (const c of t.children)
{ yield *traverse(c)
yield t.id
}
}
}
const tree =
node(1,node(5)))
console.log(Array.from(traverse(tree)).join(""))
,
您可以从 children 数组中取出可见节点并获取未可见键的节点。
const
getSequence = (key,seen = {}) => {
seen[key] = true;
const unseen = sequenceObj[key]
.children
.filter(k => !seen[k]);
return unseen.length
? `${key}${unseen.flatMap(k => getSequence(k,seen)).join(key)}${key}`
: key;
},sequenceObj = { 1: { id: "Point_1cec2262-20f8-4985-adcb-b6d95a618d22",children: ["2"] },2: { id: "Point_02bdae16-1cdb-48e1-a601-7b1e526eedb8",children: ["1","3","4","5"] },3: { id: "Point_55a68ac0-17ef-48a2-bf9f-c70004a27d99",children: ["2","6","7"] },4: { id: "Point_8760427c-98bb-4e3e-85dd-59cba3b31c6f",5: { id: "Point_79a7bcec-d110-43dc-b9ac-1552538bc1a5",6: { id: "Point_37550cf0-4bd5-48b2-b32f-9018bd55c05f",children: ["3"] },7: { id: "Point_2de67998-9e1f-4b06-af18-77d558d68254",children: ["3"] } };
console.log(getSequence('1'));
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。