Stackoverflow in BST-Algorithmus

stimmen
1

Ich habe versucht, eine Enthält Methode in meine BSTree Klasse zu implementieren, die einen Wert annehmen und dann prüfen, durch alle Knoten zu sehen, ob es in dem Baum enthalten ist. Ich denke, dass der Algorithmus korrekt ist, aber ich weiß nicht, warum ich immer wieder eine Stackoverflow in dem ersten if-Anweisung zu bekommen. Irgendwelche Ideen?

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
          }
        }        
      }
    }
Veröffentlicht am 10/08/2011 um 04:42
quelle vom benutzer
In anderen Sprachen...                            


3 antworten

stimmen
0

Ihre Logik ist falsch. Es wird nicht auf die Rückkehr falsche Aussage gehen.

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
          }
        }        
      }
    }
Beantwortet am 10/08/2011 um 04:49
quelle vom benutzer

stimmen
3

Das Problem mit dem Code ist, dass Sie den falschen Knoten in die rekursive Aufrufe vorbei sind. Nehmen wir zum Beispiel, dass Ihr Element kleiner ist als alles, was in dem Baum. Dann auf dem ersten rekursiven Aufruf, werden Sie diese Aussage getroffen:

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

Dies bedeutet , dass Sie auf der Rekursion Wurzel , nicht das linke Kind. So bei der nächsten Iteration, werden Sie feststellen , dass das Element kleiner ist als das rechte Kind der Wurzel, und so werden Sie genau die gleiche Anweisung erneut ausführen, rekursiv die gleiche Funktion aufrufen so oft , bis Sie aus dem Stapelspeicher laufen.

Um dies zu beheben, sollten Sie den obigen Code ändern zu lesen

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

Dies sagt im linken Unterbaum des aktuellen Knotens suchen, nicht der Wurzelknoten selbst. In ähnlicher Weise müssen Sie den entsprechenden Fall für den rechten Zweig aktualisieren.

Schließlich beendet diese weg, müssen Sie einen Basisfall auf Ihre rekursive Funktion hinzuzufügen, der den Fall behandelt , wo der Baum ist null, entweder , weil Sie haben den Baum oder der Baum war leer gingen weg zu beginnen. Ich lasse dies als eine Übung. :-)

Beantwortet am 10/08/2011 um 04:52
quelle vom benutzer

stimmen
0

Sie haben keine Rekursion benötigen. Sie können nur durchlaufen, so dass Sie Geta nicht Stackoverflow, auch wenn Sie einen großen Baum haben.

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;
 }
Beantwortet am 10/08/2011 um 11:47
quelle vom benutzer

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