StackOverflowException nell'algoritmo BST

voti
1

Ho cercato di implementare un metodo nella mia classe BSTree che accetterà un valore e quindi controllare attraverso tutti i nodi per vedere se è contenuto nella albero. Credo che l'algoritmo è corretto, ma non so il motivo per cui continuo a ricevere uno StackOverflowException alla prima istruzione if. Qualche idea?

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
          }
        }        
      }
    }
È pubblicato 10/08/2011 alle 04:42
fonte dall'utente
In altre lingue...                            


3 risposte

voti
0

la logica non è corretta. Non andrà alla falsa dichiarazione di ritorno.

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
          }
        }        
      }
    }
Risposto il 10/08/2011 a 04:49
fonte dall'utente

voti
3

Il problema con il vostro codice è che si sta passando il nodo sbagliato nelle chiamate ricorsive. Supponiamo, per esempio, che il vostro elemento è più piccolo di tutto l'albero. Poi sulla prima chiamata ricorsiva, ti ha colpito questa affermazione:

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

Ciò significa che è ricorsiva sulla radice , non il figlio sinistro. Così sulla prossima iterazione, troverete che l'elemento è più piccolo del figlio destro della radice, e quindi dovrete eseguire di nuovo la stessa dichiarazione precisa, chiamando ricorsivamente la stessa funzione più volte fino a quando si esaurisce lo spazio di stack.

Per risolvere questo problema, è necessario modificare il codice qui sopra per leggere

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

Questo dice di guardare nel sottoalbero sinistro del nodo corrente, non il nodo radice stessa. Allo stesso modo, è necessario aggiornare il caso corrispondente per il ramo di destra.

Infine, per concludere questa via, è necessario aggiungere un caso base alla funzione ricorsiva che gestisce il caso in cui l'albero è null, o perché hai camminato fuori l'albero o l'albero era vuota per cominciare. Lascio questo come un esercizio. :-)

Risposto il 10/08/2011 a 04:52
fonte dall'utente

voti
0

Non hai bisogno di ricorsione. Si può solo scorrere in modo da non Geta StackOverflow anche se si dispone di un enorme albero.

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;
 }
Risposto il 10/08/2011 a 11:47
fonte dall'utente

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