2011-06-04 18 views
8

Yo estoy tratando de poner en práctica Árbol recorrido en preorden usando retorno rendimiento que devuelve un IEnumerablebúsqueda binaria Árbol Transversal - preorden

private IEnumerable<T> Preorder(Node<T> node) 
{ 

    while(node != null) 
    { 
     yield return node.Data; 
     yield return node.LeftChild.Data; 
     yield return node.RightChild.Data; 
    } 

} 

En este caso, se entra en un bucle infinito y sí sé que tengo que mantener desplazamiento . ¿Cómo puede hacerse esto?

Si LeftChild o RightChild es nulo, arroja una excepción nula. Creo que en ese momento necesito un descanso en el rendimiento;

Supongo que inorder y postorder también serían similares, ¿alguna idea?

Tengo la versión Resursive, que funciona bien.

public void PreOrderTraversal(Node<T> node) 
{ 

    if(node!=null) 
    { 
     Console.Write(node.Data); 
    } 
    if (node.LeftChild != null) 
    { 
     PreOrderTraversal(node.LeftChild); 
    } 

    if (node.RightChild != null) 
    { 
     PreOrderTraversal(node.RightChild); 
    } 
} 

Gracias.

Respuesta

4

Opción # 1 Recursive

public class Node<T> : IEnumerable<T> 
{ 
    public Node<T> LeftChild { get; set; } 

    public Node<T> RightChild { get; set; } 

    public T Data { get; set; } 

    public IEnumerator<T> GetEnumerator() 
    { 
     yield return Data; 

     if (LeftChild != null) 
     { 
      foreach (var child in LeftChild) 
       yield return child; 
     } 
     if (RightChild != null) 
     { 
      foreach (var child in RightChild) 
       yield return child; 
     } 
    } 

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
} 

Uso:

var child1 = new Node<int> { Data = 1 }; 
var child2 = new Node<int> { Data = 2 }; 
var child3 = new Node<int> { Data = 3, LeftChild = child1 }; 
var root = new Node<int> { Data = 4, LeftChild = child3, RightChild = child2 }; 

foreach (var value in root) 
    Console.WriteLine(value); 

Opción # 2 no recursivo método estático

public static IEnumerable<T> Preorder<T>(Node<T> root) 
{ 
    var stack = new Stack<Node<T>>(); 
    stack.Push(root); 

    while (stack.Count > 0) 
    { 
     var node = stack.Pop(); 
     yield return node.Data; 
     if (node.RightChild != null) 
      stack.Push(node.RightChild); 
     if (node.LeftChild != null) 
      stack.Push(node.LeftChild); 
    } 
} 
+1

véase: http: // stackoverflow. com/questions/1043050/c-performance-of-nested-yield-i n-a-tree –

+0

Eso se detendrá en los niños sin atravesar más. – user7116

+0

@ user177883: su pregunta original no mencionó que la opción recursiva no es aceptable. Actualicé la respuesta con un enfoque no recursivo. –

Cuestiones relacionadas