2011-01-13 2 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) 
} 

또한 constorness를 버리는 것은 나쁘고 나쁜 생각입니다. 수정하고 싶다면 먼저 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

동일한 순서를 유지하려면 자식을 스택에 뒤로 밀어야합니다. –

관련 문제