2017-01-13 11 views
1

私はMangoesアイテムのツリーを持っていて、すべてのアイテムについて、それらをAppleに変換する処理を適用したいのですが、どのようにしてメソッドを書くことができますか?これはマンゴーツリー要素の先頭を取り、再帰なしにリンゴツリーの先頭を返します。再帰で再帰なしでツリーからツリーを構築する方法

私はこのようなものがあります:

Apple transform(Mangoe ma){  
    //Construct an apple from some modified mangoes properties 
    Apple ap = new Apple(...); 
    List<Apple> apChildren = new ArrayList<Apple>(); 
    for(Mangoe maChild:ma.getChildren()) 
     children.add(transform(maChild)); 
    ap.setChildren(children); 
    return ap; 
} 

どのように私は再帰なしでメソッドでこの動作を繰り返すことができますが?

EDIT: 私は問題を解決するために、このアルゴリズムを考えていた:

List<Mangoe> itemsToTreat = new ArrayList<Mangoe>(); 
itemsToTreat.add(ma); 

while(itemsToTreat!=null){ 
    //Apply treatment 
    //it's impossible to set the child of a created apple without recursion   

    //get the direct children of itemsToTreat 
    itemsToTreat = getDirectChildrenOfItemsToTreat(itemsToTreat); 


} 
+0

ほとんどの場合、再帰呼び出しをループと何らかの種類のスタックに置き換えることができます。見て[ここ](https://blogs.msdn.microsoft.com/ericlippert/2005/08/01/recursion-part-two-unrolling-a-recursive-function-with-an-explicit-stack/) 。結局のところ、再帰的なメソッド呼び出しは同じことを行います。つまり、同じメソッドの別の呼び出しを呼び出しスタックに置くだけで、パラメータなどに関する情報が得られます。 – Thomas

+1

再帰が何を意味するのかよくわかりません。システムスタックではなく再帰を処理するヒープ割り当てデータ構造の助けを借りて、繰り返しループとして再帰的プロセスを書くことができます。ツリーのすべてのノードに複数の子がないこと、つまりリンクされたリストがないことを必要とするため、再帰的な処理を一切行わずに行うことはできません。 – Sylwester

+0

'Tree'構造体を使用している場合は、隠れているか明示的に再帰を使わなければならないのでしょうか?たとえば、 'TreeSet'を使用している場合、iteratorを取得し、' while'ループですべての要素を調べることができます。反復子の内部では 'TreeMap.successor(Entry t)'メソッドへの複数の再帰呼び出しがあります –

答えて

0

私は、現時点では、Javaのように流暢ないですので、私はいくつかのJavaのような擬似コードといくつかの説明を使用します。この問題は、以下のようなユーザー定義のスタックによって解決できます。キーは、生成された結果を格納する場所をいくつかの情報を格納することです。再帰的実装では、コールスタックに暗黙的に行われます。これには、十分な情報だけを格納する次の補助クラスを使用します。

class AugmentedMangoe 
{ 
    public Mango iMangoe;  // Mangoe to convert 
    public Apple iParentApple; // place where to add it as child after conversion 

    public AugmentedMangoe(Mangoe iMangoe, Apple iParentApple) 
    { 
     iMangoe = iMangoe; 
     iParentApple = iParentApple; 
    } 
} 

実際の反復プロセスは、再帰をモデル化するiStackによって実行されます。

Apple transform(Mangoe ma) 
{ 
    Apple Result = null; 
    Stack<AugmentedMangoe> iStack = new Stack<AugmentedMangoe>(); 
    iStack.push(new AugmentedMangoe(ma, null)); 
    while (iStack.hasElements()) 
    { 
     // get current Mangoe 
     Mangoe iCurrentMangoe = iStack.pop(); 

     // convert Mangoe to Apple and save it 
     Apple iCurrentApple = new Apple(iCurrentMangoe.iMangoe); 

     // store the converted root, which is done only in the first iteration 
     Result = null != Result ? Result : iCurrentApple; 

     // put children to the stack 
     for(Mangoe iChild:iCurrentMangoe.iMangoe.getChildren()) 
      iStack.push(new AugmentedMangoe(iChild, iCurrentApple)); 

     // if we have stored where to put the converted object to, put it there 
     if (null != iCurrentMangoe.iParentApple) 
      iCurrentMangoe.iParentApple.addChild(iCurrentApple); 
    } 
    return Result: 
} 

それはmagnifera indicaが意図されているものとマンゴー代わりのMangoe、すべきではありませんか?

関連する問題