StackOverFlowException v BST algoritmu

hlasů
1

Byl jsem se snaží implementovat Obsahuje metodu do mého BSTree třídu, která bude přijímat hodnotu a poté kontrolovat přes všechny uzly, aby zjistil, zda je obsažen ve stromu. Domnívám se, že algoritmus je v pořádku, ale já nevím, proč jsem pořád dostat StackOverFlowException na první if. Nějaké nápady?

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
          }
        }        
      }
    }
Položena 10/08/2011 v 04:42
zdroj uživatelem
V jiných jazycích...                            


3 odpovědí

hlasů
0

Vaše logika je nesprávná. To nepůjde do zpětného falešného prohlášení.

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
          }
        }        
      }
    }
Odpovězeno 10/08/2011 v 04:49
zdroj uživatelem

hlasů
3

Problém s kódu je to, že jste prochází špatně uzel do rekurzivních volání. Předpokládejme například, že váš prvek je menší než všechno ve stromu. Pak na první rekurzivní volání, budete hit toto prohlášení:

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

To znamená, že rekurzivně na kořen , ne levé dítě. Tedy na další iteraci, zjistíte, že tento prvek je menší než pravá dítěte kořene, a tak se budete znovu spustit přesně stejný příkaz rekurzivně volá opakovaně stejnou funkci, dokud vám dojdou místa zásobníku.

Chcete-li tento problém odstranit, měli byste změnit výše uvedený kód slouží ke čtení

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

To říká, že hledat v levém podstromu aktuálního uzlu, nikoli kořen sám. Stejně tak budete muset aktualizovat odpovídající případ pro pravou větev.

A konečně, to dokončit off, budete muset přidat základní případ vaší rekurzivní funkce, která zpracovává případ, kdy je strom null, a to buď proto, že jste odešel strom nebo strom byl prázdný začít. Nechám to jako cvičení. :-)

Odpovězeno 10/08/2011 v 04:52
zdroj uživatelem

hlasů
0

Nepotřebujete rekurzi. Stačí si jen opakovat, takže nemusíte Geta StackOverflow i když máte obrovský strom.

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;
 }
Odpovězeno 10/08/2011 v 11:47
zdroj uživatelem

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