如何编写迭代 DFS 来计算树中节点的后代
我在将此代码转换
void dfs(int i = 1) {
static int preorder = 0;
d[i].first = ++preorder;
d[i].second = 1;
for (list<int>::iterator it = tree[i].begin(); it != tree[i].end(); ++it) {
dfs(*it);
d[i].second += d[*it].second;
}
}
为迭代代码时遇到问题。正如您所看到的,它找到每个节点的预序号及其有多少个后代。 由于内存限制(数据大小最多为 10^6),我必须这样做。
提前致谢。
I have problem with turning this code:
void dfs(int i = 1) {
static int preorder = 0;
d[i].first = ++preorder;
d[i].second = 1;
for (list<int>::iterator it = tree[i].begin(); it != tree[i].end(); ++it) {
dfs(*it);
d[i].second += d[*it].second;
}
}
into iterative one. As you can see, it finds preorder number of each node and how many descendants it has.
I have to do it, because of memory limitation (data size is up to 10^6).
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
DFS是一种递归算法。
如果您试图避免耗尽堆栈空间,则可以使用显式堆栈(将隐式调用堆栈转换为显式节点堆栈)。但我认为你无法摆脱它是递归算法的事实。
即使您使用显式堆栈,您仍然可能会耗尽内存。这取决于系统中的内存量以及树的形状。但在大多数情况下,它至少可以避免严重的崩溃(您可以检测到何时耗尽堆内存)。
DFS is a recursive algorithm.
If you are trying to avoid running out of stack space, you can use an explicit stack (convert the implicit call stack into an explicit node stack). But I don't think you can get away from the fact that it's a recursive algorithm.
Even if you are using an explicit stack, you could still run out of memory. That depends on the amount of memory in your system, and the shape of the tree. But in most cases it would at least avoid a nasty crash (you can detect when you run out of heap memory).
终于我弄清楚了。它可能不是那么快,但足够快地通过测试而不会消耗太多内存。我需要从孩子到他父亲的指针(只有 8 MB 数组,称为 ojciec)并检测节点是否是第一次访问(向下)或不是(向上)。
这是我的代码:
Finally I've figure it out. It may be not so fast but it is fast enough to get passed through tests without eating too much memory. I needed pointers from child to his father (just 8 MB array called ojciec) and detect if node is first time visited (going down) or not (going up).
Here is my code: