2010-08-09 6 views
0

Je suis bloqué pour trouver une solution. C#, .NET 4.0, VS2010Traverser arbitrairement un grand arbre binaire en ordre

Je peux facilement écrire un récursif, mais je ne peux pas, pour la vie de moi, trouver quelque chose qui ne débordera pas la pile si l'arbre est arbitrairement grand.

C'est une question d'arbre binaire, et je suis en train d'écrire une méthode

public IEnumerable<T> Values() 

.

Voici le code complet dans le cas où vous êtes intéressé: http://pastebin.com/xr2f3y7g

De toute évidence, la version actuellement là-bas ne fonctionne pas. Je devrais probablement mentionner que je suis un débutant en C#, en transition de C++.

+0

Pour ce que ça vaut, ce n'est pas un port horrible C#. Venant d'un fond C++, il y avait beaucoup à désapprendre ... –

Répondre

6

Voici une méthode pour afinde traversal, qui utilise la pile explicite. La pile est créée sur le tas, elle peut donc être beaucoup plus grande que la pile utilisée par le processeur.

public IEnumerable<T> Values() 
{ 
    Stack<Node> stack = new Stack<Node>(); 
    Node current = this.root; 
    while(current != null) 
    { 
     while(current.leftChild != null) 
     { 
      stack.Push(current); 
      current = current.leftChild; 
     } 
     yield return current.data; 
     while(current.rightChild == null && stack.Count > 0) 
     { 
      current = stack.Pop(); 
      yield return current.data; 
     } 
     current = current.rightChild; 
    } 

} 

Si vous ne pouvez pas utiliser une pile et vos noeuds arrive d'avoir des pointeurs de parents, vous pouvez essayer des solutions de this question

+0

À droite, vous montrez la solution de pile explicite, tout en liant à l'alternative du pointeur parent. –

+0

Cela fonctionne merveilleusement bien. En fait, j'ai aussi comment cela fonctionne. Whoa. Merci beaucoup! – CatZilla

+0

@CatZilla Je suis heureux que la réponse a aidé. S'il vous plaît envisager de l'accepter. –

0

Si l'on suppose l'arbre est loin d'équilibre, sa profondeur maximale est log2 (n), de sorte que vous auriez besoin d'un grand arbre pour déborder la pile.

Vous pouvez transformer tout algorithme récursif dans un processus itératif, mais dans ce cas, il aura probablement besoin soit des pointeurs vers l'arrière ou une pile explicite, les deux qui ont l'air cher. Cela dit, la récursivité est généralement moins bonne dans .NET car aucune variable locale dans les instances appelantes d'une méthode ne peut être GC'ed jusqu'à ce que la pile soit déroulée après la condition de terminaison. Je ne sais pas si le JIT optimisera automatiquement la récursion de queue pour la rendre itérative, mais cela aiderait.

+0

@Jimmy: D'après ce que j'ai vu du code, c'est un arbre de recherche. S'il est chargé de nombres déjà triés, il se dégradera naturellement en une liste liée de profondeur n. –

+0

D'après ce que j'ai vu du code, j'ai eu un mal de tête et a rapidement fermé l'onglet parce que je ne sais même pas ce qu'est un arbre binaire est –

+0

@Jimmy: Je ne saurais trop vous recommander apprendre les rudiments de structures de données, comprenant des arbres. C'est matériel de collège de deuxième année. –