StackOverFlowException i BST algoritme

stemmer
1

Jeg har prøvd å implementere en Inneholder metode inn i min BSTree klasse som vil godta en verdi og deretter sjekke gjennom alle nodene for å se om den finnes i treet. Jeg tror at algoritmen er riktig, men jeg vet ikke hvorfor jeg får en StackOverFlowException ved første hvis setningen. Noen ideer?

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
          }
        }        
      }
    }
Publisert på 10/08/2011 klokken 03:42
kilden bruker
På andre språk...                            


3 svar

stemmer
0

logikken er feil. Det vil ikke gå til retur falsk forklaring.

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
          }
        }        
      }
    }
Svarte 10/08/2011 kl. 03:49
kilden bruker

stemmer
3

Problemet med koden din er at du sender feil node i de rekursive samtaler. Tenk deg for eksempel at ditt element er mindre enn alt i treet. Så på den første rekursive kall, vil du treffer denne uttalelsen:

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

Dette betyr at du recurse på rot , ikke venstre barn. Dermed på neste iterasjon, vil du finne at elementet er mindre enn den høyre barn av roten, og så vil du utføre nøyaktig samme setningen igjen, rekursivt kall den samme funksjonen gjentatte ganger til du går tom for stack plass.

For å fikse dette, bør du endre koden ovenfor for å lese

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

Dette sier å se i venstre subtre av gjeldende node, ikke rotnoden selv. På samme måte må du oppdatere den tilsvarende sak for retten grenen.

Til slutt, for å fullføre dette av, må du legge en base case til rekursiv funksjon som håndterer saken hvor treet er null, enten fordi du har gått av treet eller treet var tom til å begynne med. Jeg vil forlate dette som en øvelse. :-)

Svarte 10/08/2011 kl. 03:52
kilden bruker

stemmer
0

Du trenger ikke rekursjon. Du kan bare gjenta så du trenger ikke geta Stackoverflow selv om du har et stort tre.

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;
 }
Svarte 10/08/2011 kl. 10:47
kilden bruker

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