【问题标题】:Iterating through a tree遍历一棵树
【发布时间】:2011-04-26 04:51:15
【问题描述】:

我正在试图弄清楚如何反向迭代,并通过这个向前迭代,或者至少反向调用一个方法。

这是它的工作原理。

小部件有一个 Widget* 的 std::vector,它是该控件的子控件。子向量是 z 顺序的,这意味着 child[0] 在 child[1] 之后(按渲染顺序)。每个控件都有一个指向其父级的指针,但父级为 NULL 的根(虚拟)小部件除外。

对于我的渲染,我需要做一个阶梯式的迭代(从后到前)例如:

root->child[0];
root->child[0]->child[0];
root->child[0]->child[1];
root->child[1];
root->child[1]->child[0];
root->child[1]->child[1];

但是要找到鼠标下方的小部件,我必须从前到后进行矩形测试:

   root->child[9]->child[1];
    root->child[9]->child[0];
    root->child[9];
    root->child[8]->child[2];
    root->child[8]->child[1];
    root->child[8]->child[0];
    root->child[8];

我需要什么样的迭代才能有效地完成上述 2 种迭代? (从后到前,从前到后)。

谢谢

【问题讨论】:

  • 我不确定我是否理解问题所在。这里没有链表;你有std::vectors,你可以在任一方向迭代。
  • @Oli Charlesworth 但每个 std::vector 都有孩子,也有孩子,如果不遍历父母,则无法访问某个孩子,因此是链表,
  • 我认为可能需要某种类型的递归,比如 while (children.size() > 0)
  • 这些本质上是树。您可以使用前序遍历以深度优先的方式向左遍历树(首先访问具有较小索引的子节点)或使用后序遍历向右(首先访问具有较大索引的子节点)。应该是最容易递归实现的。
  • 这不是链表,这是一棵树。

标签: c++ algorithm iteration


【解决方案1】:

前向迭代:

void blah_forward(const Widget *p)
{
    p->do_something();
    std::for_each(p->children.begin(), p->children.end(), blah_forward);
}

反向迭代:

void blah_reverse(const Widget *p)
{
    std::for_each(p->children.rbegin(), p->children.rend(), blah_reverse);
    p->do_something();
}

(未经测试,但希望您能理解)。

【讨论】:

  • 但是如果 p 有孩子,这些只做迭代,它需要递归
  • 在遍历孩子之后,反向必须为do_something()。显示的结果为后序。
【解决方案2】:

你在这里真正拥有的是一棵有有序孩子的树。如果我理解正确,您想使用Depth First Search 以相反的顺序访问孩子。因此,您只需要一些递归函数 widgetUnderMouse(Widget*) 以您想要的顺序遍历树并检查当前小部件是否在鼠标下方。我想是这样的。

Widget* widgetUnderMouse(Widget* root)
{
    if (root->hasChildren) 
    {
        vector<Widget*>::reverse_iterator rit;
        for (rit = root->child.rbegin(); rit < root->child.rend(); ++rit)
        {
            if (isWidgetUnderMouse(*rit)
            {
                return widgetUnderMouse(*rit);
            }
        }
    }
    else
    {
        return root;
    }
}

如果传入的小部件在鼠标下方,isWidgetUnderMouse 返回 true 或 false

【讨论】:

  • 你不想在这里unsigned。这正是 STL 算法旨在避免的那种车轮改造和随后的错误......
猜你喜欢
  • 2020-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-14
  • 1970-01-01
相关资源
最近更新 更多