StackOverflowException en el algoritmo BST

votos
1

He estado tratando de poner en práctica un método Contains en mi clase BSTree que acepte un valor y después comprobar a través de todos los nodos para ver si está contenido en el árbol. Creo que el algoritmo es correcto, pero no sé por qué me siguen dando un StackOverflowException en la primera sentencia if. ¿Algunas ideas?

public Boolean Contains(T item)
    {
      Node<T> node = root;
      return contains(root, item);
    }



    private Boolean contains(Node<T> node, T item)
    {
      if (item.CompareTo(root.Data) == 0)
      {
        return true;//return 0 if found
      }
      else
      {
        if (item.CompareTo(root.Data) > 0)
        {
          //root = node.Left;
          Node<T> left = root.Left;
          return(contains(root, item));
        }
        else
        {
          if (item.CompareTo(root.Data) < 0)
          {
            //root = node.Right;
            Node<T> right = root.Right;
            return(contains(root, item));
          }
          else
          {
            return false;//return 1 if not found
          }
        }        
      }
    }
Publicado el 10/08/2011 a las 04:42
fuente por usuario
En otros idiomas...                            


3 respuestas

votos
0

su lógica es incorrecta. No va a ir a la falsa instrucción de retorno.

private Boolean contains(Node<T> node, T item)
    {
      if (item.CompareTo(root.Data) == 0)
      {
        return true;//return 0 if found
      }
      else///if 0 <> 
      {
        if (item.CompareTo(root.Data) > 0)  //if 0<
        {
          //root = node.Left;
          Node<T> left = root.Left;
          return(contains(root, item));
        }
        else  //if 0>
        {
          if (item.CompareTo(root.Data) < 0) if // 0>
          {
            //root = node.Right;
            Node<T> right = root.Right;
            return(contains(root, item));
          }
          else  // this will be not executed ever
          {
            return false;//return 1 if not found
          }
        }        
      }
    }
Respondida el 10/08/2011 a las 04:49
fuente por usuario

votos
3

El problema con el código es que estás pasando el nodo mal en las llamadas recursivas. Supongamos, por ejemplo, que su elemento es menor que todo en el árbol. A continuación, en la primera llamada recursiva, llegarás a esta declaración:

Node<T> left = root.Left;
return(contains(root, item));

Esto significa que son recursivos en la raíz , no el hijo izquierdo. Así, en la siguiente iteración, usted encontrará que el elemento es menor que el hijo derecho de la raíz, y por lo que ejecuta la misma declaración exacta de nuevo, la llamada recursiva a la misma función repetidamente hasta que se quede sin espacio de pila.

Para solucionar este problema, debe cambiar el código de arriba para leer

Node<T> left = node.Left;
return(contains(left, item));

Este dice que buscar en el subárbol izquierdo del nodo actual, no es el nodo raíz en sí. Del mismo modo, tendrá que actualizar el caso correspondiente a la rama derecha.

Por último, para terminar esto, tendrá que añadir un caso base a su función recursiva que maneja el caso en que el árbol es null, ya sea porque usted ha caminado fuera del árbol o el árbol estaba vacío, para empezar. Voy a dejar esto como un ejercicio. :-)

Respondida el 10/08/2011 a las 04:52
fuente por usuario

votos
0

No es necesario recursividad. Usted puede simplemente repetir lo que no geta Stackoverflow incluso si tiene un enorme árbol.

public Boolean Contains(T item) {
    Node<T> currentNode = root;

    while(currentNode != null) { // Or whatever you use to signal that there is no node.
        switch(item.CompareTo(currentNode.Data)) {
            case -1:
                currentNode = currentNode.Right;
                break;
            case 1:
                currentNode = currentNode.Left;
                break;
            default: // case 0
                return true;
        }
    }
    return false;
 }
Respondida el 10/08/2011 a las 11:47
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more