有限的空间迭代器

发布于 2025-01-31 20:19:02 字数 394 浏览 2 评论 0原文

我已经实现了一棵树(不是二进制树,每个节点都有几个子节点)。对于每个节点,我们都可以在树,孩子和父节点中访问其水平。

下一阶段是为这棵树实现2个迭代器,但捕获是我不能节省超过恒定数量的信息来帮助完成这些迭代器(即恒定的空间复杂性)。

我的问题是我目前处于的一个节点n:

  1. 在BFS顺序中找到下一个遍历的节点是什么算法?
  2. 在 *反向BFS顺序中找到下一个遍历的节点是什么算法?

*注意:

反向BFS正在以相反顺序横穿水平,例如以下树的反向BF

      1 
    / | \
   2  3  4
  /  / \  \
 5  6   7  8

为5 6 7 8,然后2 3 4,然后是1。

I've implemented a tree (not a binary tree, every node can have several child nodes). For every node, we can access its level in the tree, its children and its parent node.

The next phase is to implement 2 iterators for this tree but the catch is I can not save more than a constant amount of information to help complete these iterators (i.e constant space complexity).

My questions are, given a node n that I'm currently at:

  1. What would be the algorithm to find the next node to traverse in a BFS order?
  2. What would be the algorithm to find the next node to traverse in a *Reverse BFS order?

*Note:

Reverse BFS is traversing the levels in reverse order e.g Reverse BFS of the following tree

      1 
    / | \
   2  3  4
  /  / \  \
 5  6   7  8

would be 5 6 7 8 then 2 3 4 and then 1.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

妄司 2025-02-07 20:19:02

这是算法的草图。效率低下,但满足您仅使用O(1)额外空间的要求。

  1. node* goright(node* c)
    如果c是root(没有父母),请返回null
    pc的父母。立即在c的右边找到其子女r(可能需要对p的子女链接进行线性搜索)。如果找到,返回r
    如果找不到(c是最正确的孩子),set c = p,从一开始就重复。

因此,发现的节点可能比我们开始的节点更高。

  1. 节点* godowntolevel(node* p,int k)
    如果pnull,返回null
    如果p在级别k,返回p
    p开始,请按照左侧的儿童链接向下链接,直到达到级别k或无需链接。令c为因此找到的节点。如果c在级别k,返回c
    否则,ck上方的级别节点。 SET P = Goright(C),从开始时重复。

  2. node* nextAtlevel(node* c,int k)
    返回godowntolevel(goright(c),k)

  3. node* nextinbfsorder(node* c)

    kc的级别。令r = nextAtlevel(c,k)。如果r不是null,返回r
    否则,将父链一直穿过根,返回godowntolevel(root,k+1)。另外,root可以存储在迭代器中。另外,迭代器可以跟踪它在遍历级别k时遇到的第一个非叶节点的最左边的孩子,然后跳到该孩子,一旦NextAtlevel失败;这个孩子在级别开始迭代k+1



反向BF会类似地工作。困难的部分是找到启动遍历的节点。基本上,执行godowntolevel(root,infinity),同时跟踪遇到的最深层次,并在该级别遇到的第一个节点。当然,do godowntolevel(root,k-1)而不是godownTolevel(root,k+1) nextAtlevel失败。

如果您在建造树时跟踪h,则可以使用godowntolevel(root,h)启动遍历

Here's a sketch of the algorithm. Very inefficient, but satisfies your requirement of only using O(1) additional space.

  1. Node* GoRight(Node* c)
    If c is root (there's no parent), return NULL
    Let p be the parent of c. Find its child r immediately to the right of c (may need to do a linear search of p's child links). If found, return r
    If not found (c is the right-most child), set c=p, repeat from the start.

The node thus found may be at a higher level than the node we started with.

  1. Node* GoDownToLevel(Node* p, int k)
    If p is NULL, return NULL
    If p is at level k, return p.
    Starting from p, follow the left-most child links down until level k is reached or there are no links to follow. Let c be the node thus found. If c is at level k, return c.
    Otherwise, c is a leaf node at a level above k. Set p = GoRight(c), repeat from the start.

  2. Node* NextAtLevel(Node* c, int k)
    Return GoDownToLevel(GoRight(c), k)

  3. Node* NextInBFSOrder(Node* c)
    Let k be the level of c. Let r = NextAtLevel(c, k). If r is not NULL, return r.
    Otherwise, traverse the parent chain all the way to the root, return GoDownToLevel(root, k+1). Alternatively, root could be stored in the iterator. Alternatively, the iterator could keep track of the leftmost child of the first non-leaf node it encountered while traversing level k, and jump to that child once NextAtLevel fails; this child starts the iteration at level k+1.


Reverse BFS would work similarly. The hard part is finding the node to start the traversal from. Basically, perform GoDownToLevel(root, infinity) while keeping track of the deepest level encountered and the first node encountered at that level. And of course, do GoDownToLevel(root, k-1) instead of GoDownToLevel(root, k+1) when NextAtLevel fails.

If you keep track of the height h of the tree while its being built, then you can start the traversal with GoDownToLevel(root, h)

稀香 2025-02-07 20:19:02

我假设您可以弄清楚如何进行树的预订遍历:先扎根,然后再去第一个孩子,直到您没有孩子碰到节点。然后去找父母,然后在您来自一个孩子之后找到下一个孩子。如果这是最后一个孩子与新父母重复。

一次这样做以找出树的最深节点,或者使树存储的最大深度。然后,再做一个深度的第一个孩子。您的迭代器是那个深度和孩子的地址。

要增加迭代器,请继续对孩子进行预订遍历,然后跳过所有节点,其中node-> depth!= depth。每次遍历饰面都会减小深度。当深度变为负返回end()时。

注意:在预订遍历中,您可以在node-> depth == depth 时跳到孩子身上,直接回到父母身上。

I assume you can figure out how to do an pre-order traversal of the tree: Take the root first, then go to the first child till you hit a node with no children. Then go to the parent and find the next child after the one you came from. If it was the last child repeat with the new parent.

Do this once to find out the deepest node of the tree, or have the tree store its max depth. Then do it again stopping at the first child with that depth. Your iterator is that depth and the address of the child.

To increment the iterator keep doing pre-order traversal on the child and skip all the nodes where node->depth != depth. Each time the traversal finishes decrement depth. When depth becomes negative return end().

Note: in the pre-order traversal you can skip going down to children when node->depth == depth, go straight back to parent.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文