javascript - 迭代树序列化函数
问题描述
这是我正在使用的树和所需的字符串序列化的可视化表示:
这是一个递归解决方案:
function* serialize(root) {
if (root.length === 0)
return;
const [x, xs] = root;
yield x;
for (let i = 0; i < xs.length; i++)
yield* serialize(xs[i]);
yield ")";
}
const Node = (x, ...xs) => ([x, xs]);
const tree = Node("a",
Node("b",
Node("e"),
Node("f",
Node("k"))),
Node("c"),
Node("d",
Node("g"),
Node("h"),
Node("i"),
Node("j")));
console.log(
Array.from(serialize(tree)).join("")); // abe)fk)))c)dg)h)i)j)))
显然,它可以工作,但对于非常深的树来说不是安全的。我怎样才能将它转换成它的迭代对应物?
我知道我需要一个堆栈。但我无法弄清楚细节。我对这种转变的基本机制特别感兴趣。
我设法创建了一个迭代的前序遍历,但奇怪的是,这对迭代序列化它没有帮助:
const Node = (x, ...xs) => ([x, xs]);
const tree = Node("a",
Node("b",
Node("e"),
Node("f",
Node("k"))),
Node("c"),
Node("d",
Node("g"),
Node("h"),
Node("i"),
Node("j")));
function* preOrderIt(root) {
if (root.length === 0)
return;
const stack = [root];
while (stack.length > 0) {
let [x, xs] = stack.pop();
for (let i = xs.length - 1; i >= 0; i--)
stack.push(xs[i]);
yield x;
}
}
console.log(
Array.from(preOrderIt(tree)).join("")); // abefkcdghij
解决方案
您的序列化基本上为每个节点添加了一个额外的虚拟子节点,因此您必须在迭代时“访问”它:
const Node = (x, ...xs) => ([x, xs]);
const tree = Node("a",
Node("b",
Node("e"),
Node("f",
Node("k"))),
Node("c"),
Node("d",
Node("g"),
Node("h"),
Node("i"),
Node("j")));
function* preOrderIt(root) {
if (root.length === 0)
return;
const stack = [root];
while (stack.length > 0) {
let [x, xs] = stack.pop();
if (x !== ')') // <-
stack.push([')', []]); // <-
for (let i = xs.length - 1; i >= 0; i--)
stack.push(xs[i]);
yield x;
}
}
console.log(
Array.from(preOrderIt(tree)).join(""));
推荐阅读
- php - 使用 php 更新和重新加载 mysql - 删除确认问题
- javascript - 使用 PHP 和 JS 的 While 循环中的 SQL 查询不工作
- oracle - 如何使用一个程序插入两个表
- python - 如何使用 tokezine/untokenize?
- laravel - 访问关注者数据 Laravel 5.8 和 Eloquent
- math - 标记数据的离散度测量
- c++ - 对 Google CodeJam 2018 预选赛进行故障排序
- .net - 无法访问已处置的对象。此错误的常见原因是处理上下文
- haskell - 为什么这个单射类型族实际上不是单射的?
- maven - jenkins(openshift) chrome 节点上的“org.openqa.selenium.WebDriverException:未知错误:Chrome 无法启动:异常退出”问题