2011-01-13 4 views
2

У меня есть функция, которая рекурсивна, но вместо этого я хотел бы сделать ее нерекурсивной. Я просто не знаю, как это сделать.Сделать эту функцию нерекурсивной?

void AguiWidgetManager::recursiveRender(const AguiWidget *root) 
{ 
    //recursively calls itself to render widgets from back to front 
    AguiWidget* nonConstRoot = (AguiWidget*)root; 
    if(!nonConstRoot->isVisable()) 
    { 
     return; 
    } 

     clip(nonConstRoot); 

     nonConstRoot->paint(AguiPaintEventArgs(true,graphicsContext)); 

     for(std::vector<AguiWidget*>::const_iterator it = 
      root->getPrivateChildBeginIterator(); 
      it != root->getPrivateChildEndIterator(); ++it) 
     { 
      recursiveRender(*it); 
     } 
     for(std::vector<AguiWidget*>::const_iterator it = 
      root->getChildBeginIterator(); 
      it != root->getChildEndIterator(); ++it) 
     { 
      recursiveRender(*it); 
     } 

} 

Его хорошо, если решение не будет работать с итераторами.

Благодаря

+6

Знаете, если вы сделаете эту функцию нерекурсивной, она будет очень плохо названа. –

+0

Могу я спросить, почему? Я думаю, что рекурсия, вероятно, самый простой способ сделать это. Итеративное решение, вероятно, будет использовать стек и вручную реализовать рекурсию. Кроме того, 'std :: for_each (root-> getChildBeginIterator(), root-> getChildEndIterator(), recursiveRender);' выглядит немного лучше, чем у вас. –

+0

@Chris Lutz 'for_each' может выглядеть лучше, но если я не ошибаюсь, так как функция является функцией-членом, вам нужно связывание' mem_fun_ref' или что-то подобное, чтобы заставить его правильно позвонить. –

ответ

6

Самый простой способ, это просто поддерживать свой собственный стек. Пример кода псевдуиста:

stack s; 
while(!s.empty()) 
{ 
    root = s.pop(); 

    //your code here 
    //replace each recursive call with s.push(it) 
} 

Кроме того, отбрасывание константы - плохая, плохая идея. Он не должен быть аргументом const, если вы хотите его изменить.

+1

+1 для литья 'const'. –

+3

Не забудьте нажать что-нибудь в стек, чтобы получить первую итерацию! –

1

В общем, вам нужно будет реализовать стек себя:

clear stack 
push first item onto stack 
while stack is not empty: 
    pop top item off stack 
    do action for item (clip, paint) 
    push children onto stack (if any) 
+0

Возможно, вы захотите отметить, что дети должны были быть сдвинуты в стек назад для поддержания того же порядка. –

Смежные вопросы