Я понимаю, что этот пост несколько лет, но ни один из ответов не кажется, прямо ответить на вопрос, так что я решил написать что-то несколько простых ,
Это предполагает целочисленный индексированный граф; но вы можете, конечно, приспособить его по мере необходимости. Ключ к выполнению DFS итеративно и до сих пор выполняющий операции предварительного заказа/пост-заказа - это НЕ только добавлять к каждому ребенку, но вместо этого вести себя точно так же, как рекурсивный DFS, который добавляет только один дочерний узел в стек в то время, и только удаляя их из стека после его завершения. Я делаю это в своем примере, создав узел-оболочку с списком смежности в виде стека. Просто опускаем проверку цикла, если вы хотите, чтобы циклы (не траверс посещенных узлов в любом случае, так что он все равно будет работать)
class Stack(object):
def __init__(self, l=None):
if l is None:
self._l = []
else:
self._l = l
return
def pop(self):
return self._l.pop()
def peek(self):
return self._l[-1]
def push(self, value):
self._l.append(value)
return
def __len__(self):
return len(self._l)
class NodeWrapper(object):
def __init__(self, graph, v):
self.v = v
self.children = Stack(graph[v])
return
def iterative_postorder(G, s):
onstack = [False] * len(G)
edgeto = [None] * len(G)
visited = [False] * len(G)
st = Stack()
st.push(NodeWrapper(G, s))
while len(st) > 0:
vnode = st.peek()
v = vnode.v
if not onstack[v]:
print "Starting %d" % (v)
visited[v] = True
onstack[v] = True
if len(vnode.children) > 0:
e = vnode.children.pop()
if onstack[e]:
cycle = [e]
e = v
while e != cycle[0]:
cycle.append(e)
e = edgeto[e]
raise StandardError("cycle detected: %s, graph not acyclic" % (cycle))
if not visited[e]:
edgeto[e] = v
st.push(NodeWrapper(G, e))
else:
vnode = st.pop()
onstack[vnode.v] = False
print 'Completed %d' % (vnode.v)
Довольно общий вопрос, с довольно специфическими требованиями;). Как насчет того, чтобы просто просить подсказки об итеративном обходе - pre/post ops будет, чем просто вписываться;). –
Похоже, «может ли кто-нибудь показать мне, как перебирать массив и выполнять функцию для каждого элемента». В чем проблема с повторением этого шаг за шагом, как вы описали? –
Каждый родитель должен быть посещен до того, как его дети (предварительная операция), а затем посетит еще раз после его детей (после операции). Мы теряем этот контекст, когда мы перебираем массив. Легко сделать рекурсивно, но это бьет меня, как это сделать итеративно. – xeolabs