StackOverFlowException în algoritmul BST

voturi
1

Am încercat să pună în aplicare o metodă în clasa mea BSTree că va accepta o valoare și apoi verificați prin toate nodurile pentru a vedea dacă acesta este conținut în arbore conține. Cred că algoritmul este corect, dar eu nu știu de ce am păstra achiziție o StackOverFlowException la prima if. Vreo idee?

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
          }
        }        
      }
    }
Întrebat 10/08/2011 la 04:42
sursa de către utilizator
În alte limbi...                            


3 răspunsuri

voturi
0

logica este incorect. Nu va merge la declarația falsă de returnare.

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
          }
        }        
      }
    }
Publicat 10/08/2011 la 04:49
sursa de către utilizator

voturi
3

Problema cu codul dvs. este că sunteți care trece nodul greșit în apelurile recursive. Să presupunem, de exemplu, că elementul este mai mic decât totul în copac. Apoi, pe primul apel recursiv, vei lovi această declarație:

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

Acest lucru înseamnă că recurse la rădăcină , nu copilul stâng. Astfel , la urmatoarea iteratie, veți găsi că elementul este mai mică decât copilul din dreapta al rădăcinii, și deci va executa din nou aceeași declarație exactă, apel recursiv aceeași funcție în mod repetat , până când a alerga afară de spațiu stivă.

Pentru a remedia acest lucru, ar trebui să schimbați codul de mai sus pentru a citi

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

Acest lucru spune să se uite în subarborele stâng al nodului curent, nu nodul rădăcină în sine. În mod similar, va trebui să actualizați cazul corespunzător pentru ramura dreapta.

În cele din urmă, pentru a termina acest off, va trebui să adăugați un caz de bază pentru funcția recursive care se ocupa de cazul în care arborele este null, fie pentru că ai umblat pe copac sau copac a fost gol pentru a începe cu. Voi lăsa acest lucru ca un exercițiu. :-)

Publicat 10/08/2011 la 04:52
sursa de către utilizator

voturi
0

Nu ai nevoie de recurență. Puteți itera pur și simplu, astfel încât să nu GETA StackOverflow, chiar dacă aveți un copac imens.

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;
 }
Publicat 10/08/2011 la 11:47
sursa de către utilizator

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