2016-03-26 9 views
2

私は、再帰を使用せずに実装したい変更済みプリオーダーツリートラバーサルnested set modelを再帰的に実装しています。スタックベースの修正済みプリオーダーツリートラバーサル

from collections import deque 

def mptt_recurse(tree, node, preorder=None): 

    if node not in tree: return 
    if preorder is None: preorder = deque() 

    for child in tree[node]: 
     preorder.append(child) 
     mptt_recurse(tree, child, preorder) 
     preorder.append(child) 

    return preorder 

再帰的な実装が期待どおりに動作:

>>> tree = { 
    "root": ["food"], 
    "food": ["meat", "veg"], 
    "meat": ["pork", "lamb"], 
    "pork": ["bacon", "sausage"], 
    "lamb": ["cutlet"], 
    "soup": ["leak", "tomato"] 
} 
>>> mptt_recuser(tree, "root") 
deque(['food', 'meat', 'pork', 'bacon', 'bacon', 'sausage', 'sausage', 'pork', 'lamb', 'cutlet', 'cutlet', 'lamb', 'meat', 'veg', 'veg', 'food']) 

各ノードはdeque内の位置によって表される左右の値で二回表示されます。私のスタックベースの実装では

def mptt_stack(tree, node): 

    if node not in tree: return 
    stack = deque(tree[node]) 
    preorder = deque() 

    while stack: 
     node = stack.pop() 
     preorder.append(node) 
     if node not in tree: 
      continue 
     for child in reversed(tree[node]): 
      stack.append(child) 

    return preorder 

私は前順(各ノードの左と右のラベルの両方でない修正前順)を取得する方法を見つけ出すことができました。

>>> mptt_stack(tree, "root") 
deque(['food', 'meat', 'pork', 'bacon', 'sausage', 'lamb', 'cutlet', 'veg']) 

非再帰的実装では、どのポインタも優れています。

答えて

1

この結果は、mptt_recurseと同じ結果になります。それはノードを入力するか、残していますかどうかを示す、スタック上の情報の追加部分を保持します:

def mptt_stack(tree, node): 
    if node not in tree: return 
    preorder = deque() 

    stack = [] 
    for child in reversed(tree[node]): 
     stack.append([child, True]) 

    while stack: 
     (node, first) = stack.pop() 
     preorder.append(node) 
     if first: 
      stack.append([node, False]) 
      if node in tree: 
       for child in reversed(tree[node]): 
        stack.append([child, True]) 

    return preorder 

あなたは結果に最初のノードを含めたい場合は、あなたとstackを初期化ループを置き換えることができます。

stack = [[node, True]] 
関連する問題