Eu tenho uma árvore de nós de memória muito grande e preciso atravessá-la. Passando os valores retornados de cada nó filho para o nó pai. Isso deve ser feito até que todos os nós tenham seus dados em bolha até o nó raiz.
O Traversal funciona assim.
private Data Execute(Node pNode)
{
Data[] values = new Data[pNode.Children.Count];
for(int i=0; i < pNode.Children.Count; i++)
{
values[i] = Execute(pNode.Children[i]); // recursive
}
return pNode.Process(values);
}
public void Start(Node pRoot)
{
Data result = Execute(pRoot);
}
Isso funciona bem, mas estou preocupado que a pilha de chamadas limite o tamanho da árvore de nós.
Como o código pode ser reescrito para que não Execute
sejam feitas chamadas recursivas ?
c#
optimization
trees
Reactgular
fonte
fonte
Respostas:
Aqui está uma implementação transversal de árvore de uso geral que não usa recursão:
No seu caso, você pode chamá-lo assim:
Use uma pesquisa em
Queue
vez de aStack
para respirar primeiro, em vez da profundidade primeiro. Use aPriorityQueue
para obter a melhor primeira pesquisa.fonte
Se você tem uma estimativa da profundidade da sua árvore de antemão, talvez seja suficiente para o seu caso adaptar o tamanho da pilha? No C # desde a versão 2.0, isso é possível sempre que você inicia um novo thread, veja aqui:
http://www.atalasoft.com/cs/blogs/rickm/archive/2008/04/22/increasing-the-size-of-your-stack-net-memory-management-part-3.aspx
Dessa forma, você pode manter seu código recursivo, sem precisar implementar algo mais complexo. Obviamente, criar uma solução não recursiva com sua própria pilha pode ser mais eficiente em termos de tempo e memória, mas tenho certeza de que o código não será tão simples quanto é por enquanto.
fonte
Você não pode atravessar uma estrutura de dados na forma de uma árvore sem usar recursão - se você não usar os quadros de pilha e as chamadas de função fornecidas pelo seu idioma, basicamente precisará programar suas próprias chamadas de pilha e função, e é improvável que você consiga fazê-lo na linguagem de maneira mais eficiente do que os escritores do compilador fizeram na máquina em que seu programa seria executado.
Portanto, evitar recursões por medo de atingir os limites de recursos geralmente é equivocado. Para garantir, a otimização prematura de recursos é sempre equivocada, mas, neste caso, é provável que, mesmo que você avalie e confirme que o uso de memória é o gargalo, provavelmente não será possível aprimorá-lo sem diminuir o nível do escritor do compilador.
fonte