StackOverFlowException σε αλγόριθμο BST

ψήφοι
1

Έχω προσπαθήσει να εφαρμόσει μια μέθοδο στην κατηγορία BSTree μου, που θα δεχθεί μια τιμή και στη συνέχεια ελέγξτε μέσα από το σύνολο των κόμβων για να δούμε αν περιέχεται στο δέντρο Περιέχει. Νομίζω ότι ο αλγόριθμος είναι σωστός, αλλά δεν ξέρω γιατί συνεχίζω να πάρει ένα StackOverFlowException στο πρώτο if. Καμιά ιδέα?

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
          }
        }        
      }
    }
Δημοσιεύθηκε 10/08/2011 στις 04:42
πηγή χρήστη
Σε άλλες γλώσσες...                            


3 απαντήσεις

ψήφοι
0

τη λογική σας είναι λανθασμένη. Δεν θα πάει στην επιστροφή ψευδή δήλωση.

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
          }
        }        
      }
    }
Απαντήθηκε 10/08/2011 στις 04:49
πηγή χρήστη

ψήφοι
3

Το πρόβλημα με τον κωδικό σας είναι ότι είστε περνώντας το λάθος κόμβο στις αναδρομικές κλήσεις. Ας υποθέσουμε, για παράδειγμα, ότι το στοιχείο σας είναι μικρότερη από ό, τι στο δέντρο. Στη συνέχεια, στην πρώτη αναδρομική κλήση, θα χτυπήσει αυτή τη δήλωση:

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

Αυτό σημαίνει ότι μπορείτε recurse στην ρίζα , δεν το αριστερό παιδί. Έτσι, για την επόμενη επανάληψη, θα διαπιστώσετε ότι το στοιχείο είναι μικρότερο από το δικαίωμα του παιδιού της ρίζας και έτσι θα εκτελέσει την ίδια ακριβώς δήλωση και πάλι, αναδρομικά καλώντας την ίδια λειτουργία επανειλημμένα μέχρι να εξαντληθεί ο χώρος στοίβας.

Για να διορθώσετε αυτό, θα πρέπει να αλλάξετε τον παραπάνω κώδικα για να διαβάσετε

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

Αυτό λέει να κοιτάξουμε στο αριστερό υποδένδρο του τρέχοντος κόμβου, όχι το ίδιο το ριζικό κόμβο. Ομοίως, θα πρέπει να ενημερώσετε την αντίστοιχη περίπτωση του δεξιού κλάδου.

Τέλος, για να τελειώσει αυτό το off, θα χρειαστεί να προσθέσετε ένα βασικό σενάριο για την αναδρομική σας λειτουργία που χειρίζεται την υπόθεση, όπου το δέντρο είναι null, είτε επειδή έχετε περπατήσει από το δέντρο ή το δέντρο ήταν κενό για να αρχίσει με. Θα αφήσω αυτό ως μια άσκηση. :-)

Απαντήθηκε 10/08/2011 στις 04:52
πηγή χρήστη

ψήφοι
0

Δεν χρειάζεται αναδρομή. Μπορείτε απλά να επαναλάβουμε, ώστε να μην Geta StackOverflow ακόμη και αν έχετε ένα τεράστιο δέντρο.

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;
 }
Απαντήθηκε 10/08/2011 στις 11:47
πηγή χρήστη

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