Стандартный рефакторинг заключается в том, чтобы хранить данные, которые в противном случае передавались бы функции, в очередь LIFO (то есть в стек) или в очередь FIFO. Обратите внимание, что это не меняет асимптотическое использование пространства; вы используете свою собственную структуру данных, а не стек вызовов.
Если вы можете определить функцию «следующего брата», вы можете посещать узлы с постоянным дополнительным пробелом. Это связано с тем, что граф каталогов (без файлов) по существу является ненаправленным из-за родительских указателей. Псевдокод:
nextBranchingSibling(sibling):
while sibling exists
if sibling has children
return sibling
sibling = nextSibling(sibling)
return null
nextBranch(node):
if node is marked
unmark node
else
if nextBranchingSibling(firstChild(node)) exists
return nextBranchingSibling(firstChild(node))
if nextBranchingSibling(nextSibling(node)) exists
return nextBranchingSibling(nextSibling(node))
mark parent(node)
return parent(node)
prune(node):
while node exists:
tmpNode = node
node = nextBranch(node)
if count of tmpNode's children is 0
delete tmpNode
Обратите внимание, что вы фактически не используете O (1) всего пространства, поскольку структура каталогов сама по себе O (n). Методы типа DirectoryInfo.GetDirectories
могут устранить необходимость в циклах в nextBranchingSibling
.