通过一棵树迭代

时间:2010-10-15 23:31:42

标签: c++ algorithm iteration

我正在试图弄清楚如何反向迭代,然后转发,或者至少反向调用一个方法。

以下是它的工作原理。

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

对于我的渲染,我需要做一个阶梯式的迭代(回到前面)ex:

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 个答案:

答案 0 :(得分:6)

转发迭代:

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();
}

(未经测试,但希望你能得到这个想法)。

答案 1 :(得分:0)

你真正拥有的是一棵有序儿童的树。如果我理解正确,你想用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