2011-01-13 9 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 constessionをキャストするのは悪いことですが、悪い考えです。もしそれを変更したいのであれば、最初は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

同じ順序を維持するために、子供がスタックに後方に押し込まれなければならないことに注意してください。 –

関連する問題