θέμα τύπου Java Γενική Binary Search Tree

ψήφοι
1

Δουλεύω σε αυτό το σπίτι που είναι είδος σύγχυση μου ...

Είμαι παρέχονται με την ακόλουθη κατηγορία BinarySearchTree

import java.util.NoSuchElementException;

/**
 *
 * @param <T> The type of data stored in the nodes of the tree, must implement  Comparable<T> with the compareTo method.
 */
public class BinarySearchTree<T extends Comparable<T>> {


    BinaryTree<T> tree;

    int size;
    public BinarySearchTree() {
        tree = new BinaryTree<T>();
        size = 0;
    }

    public boolean isEmpty() {
        return tree.isEmpty();
    }

    protected BinaryTree<T> recursiveSearch(BinaryTree<T> root, T key) {
        if (root == null) {
            return null;
        }
        int c = key.compareTo(root.data);
        if (c == 0) {
            return root;
        }
        if (c < 0) {
            return recursiveSearch(root.left, key);
        } else {
            return recursiveSearch(root.right, key);
        }
    }

    public T search(T key) {
        if (tree.isEmpty()) { 
            return null;
        }
        return recursiveSearch(tree, key).data;
    }

    public void insert(T item) {

        if (tree.isEmpty()) { // insert here
            tree.makeRoot(item);
            size++;
            return;
        }

        // do an iterative descent
        BinaryTree<T> root = tree;
        boolean done=false;
        BinaryTree<T> newNode = null;
        while (!done) {
            int c = item.compareTo(root.data);
            if (c == 0) { // duplicate found, cannot be inserted
                throw new OrderViolationException();
            }
            if (c < 0) { // insert in left subtree
                if (root.left == null) { // insert here as left child
                    newNode = new BinaryTree<T>();
                    root.left = newNode;
                    done=true;
                } else { // go further down left subtree
                    root = root.left;
                }
            } else { // insert in right subtree
                if (root.right == null) { // insert here as right child 
                    newNode = new BinaryTree<T>();
                    root.right = newNode;
                    done=true;
                } else { // go further down right subtree
                    root = root.right;
                }
            }
        }
        // set fields of new node
        newNode.data = item;
        newNode.parent = root;
        size++;
    }

    /**
     * @param deleteNode Node whose parent will receive new node as right or left child,
     *                  depending on whether this node is its parent's right or left child. 
     * @param attach The node to be attached to parent of deleteNode.
     */
    protected void deleteHere(BinaryTree<T> deleteNode, BinaryTree<T> attach) {

        // deleteNode has only one subtree, attach
        BinaryTree<T> parent = deleteNode.parent;
        deleteNode.clear();  // clear the fields
        if (parent == null) {
            return;
        }
        if (deleteNode == parent.left) {
            // left child of parent, attach as left subtree
            parent.detachLeft();
            parent.attachLeft(attach);
            return;
        }
        // attach as right subtree
        parent.detachRight();
        parent.attachRight(attach);
    }


    protected BinaryTree<T> findPredecessor(BinaryTree<T> node) {
        if (node.left == null) {
            return null;
        }
        BinaryTree<T> pred = node.left; // turn left once
        while (pred.right != null) { // keep turning right
            pred = pred.right;
        }
        return pred;
    }


    public T delete(T key) {
        if (tree.isEmpty()) { // can't delete from an empty tree
            throw new NoSuchElementException();
        }

        // find node containing key 
        BinaryTree<T> deleteNode = recursiveSearch(tree, key);
        if (deleteNode == null) { // data not found, can't delete
            throw new NoSuchElementException();
        }

        BinaryTree<T> hold;

        // case c: deleteNode has exactly two subtrees
        if (deleteNode.right != null && deleteNode.left != null) {
            hold = findPredecessor(deleteNode);
            deleteNode.data = hold.data;
            deleteNode = hold; // fall through to case a or b
        }

        // case a: deleteNode is a leaf
        if (deleteNode.left == null && deleteNode.right == null) {
            deleteHere(deleteNode, null);
            size--;
            return deleteNode.data;
        }       

        // case b: deleteNode has exactly one subtree
        if (deleteNode.right != null) {
            hold = deleteNode.right;
            deleteNode.right = null;
        } else {
            hold = deleteNode.left;
            deleteNode.left = null;
        }

        deleteHere(deleteNode,hold);
        if (tree == deleteNode) { // root deleted
            tree = hold;
        }
        size--;
        return deleteNode.data;
    }


    public T minKey() {
        if (tree.data == null) { // tree empty, can't find min value
            throw new NoSuchElementException();
        }

        BinaryTree<T> root = tree;
        T min=root.data;
        root = root.left;  // turn left once
        while (root != null) {  // keep going left to leftmost node
            min = root.data;
            root = root.left;
        }
        return min;
    }


    public T maxKey() {
        if (tree.getData() == null) { // tree empty, can't find max value
            throw new NoSuchElementException();
        }

        BinaryTree<T> root=tree;
        T max=root.data;
        root = root.right;  // turn right once
        while (root != null) { // keep going to rightmost node
            max = root.data;
            root = root.right;
        }
        return max;
    }


    public int size() {
        return size;
    }


    protected void recursivePreOrder(BinaryTree<T> root, Visitor<T> visitor) {
        if (root != null) {
            visitor.visit(root);
            recursivePreOrder(root.left, visitor);
            recursivePreOrder(root.right, visitor);
        }
    }


    public void preOrder(Visitor<T> visitor) {
        if (tree.isEmpty()) {
            return;
        }
        recursivePreOrder(tree, visitor);
    }


    protected void recursiveInOrder(BinaryTree<T> root, Visitor<T> visitor) {
        if (root != null) {
            recursiveInOrder(root.left, visitor);
            visitor.visit(root);
            recursiveInOrder(root.right, visitor);
        }
    }


    public void inOrder(Visitor<T> visitor) {
        if (tree.isEmpty()) {   
            return;
        }
        recursiveInOrder(tree, visitor);
    }


    protected void recursivePostOrder(BinaryTree<T> root, Visitor<T> visitor) {
        if (root != null) {
            recursivePostOrder(root.left, visitor);
            recursivePostOrder(root.right, visitor);
            visitor.visit(root);
        }
    }

    public void postOrder(Visitor<T> visitor) {
        if (tree.isEmpty()) {
            return;
        }
        recursivePostOrder(tree, visitor);
    }
}

================================================== ==============================

Τώρα έχω μια άλλη κατηγορία φοιτητών .... Θέλω να δημιουργήσω ένα δυαδικό δέντρο αναζήτησης αντικειμένων Φοιτητών ..

BinarySearchTree<Student> tree = new BinarySearchTree<Student>();

Ωστόσο, όταν το κάνω αυτό παίρνω το ακόλουθο μήνυμα λάθους:

Δεσμώτης αναντιστοιχία: Η Φοιτητική τύπος δεν είναι έγκυρο υποκατάστατο για το φραγμένο παράμετρο> του BinarySearchTree τύπου

Οποιεσδήποτε ιδέες τι συμβαίνει εδώ ... Δεν μπορώ να το καταλάβω.

Δημοσιεύθηκε 02/05/2009 στις 06:31
πηγή χρήστη
Σε άλλες γλώσσες...                            


3 απαντήσεις

ψήφοι
0

Μήπως η Φοιτητική τάξη εφαρμογή Συγκρίσιμα;

Απαντήθηκε 02/05/2009 στις 06:41
πηγή χρήστη

ψήφοι
0

αλλά δεν είμαι βέβαιος πώς να εφαρμόσουν τη μέθοδο compareTo.

Βασικά είναι κάτι σαν το παρακάτω. Πώς λειτουργεί η παραγγελία θα πρέπει να αποφασίσει.

class Student implements Comparable<Student> {

    //...

    int compareTo(Student other) {
        // return some negative number if this object is less than other
        // return 0 if this object is equal to other
        // return some positive number if this object is greater than other
    }
}
Απαντήθηκε 02/05/2009 στις 06:56
πηγή χρήστη

ψήφοι
6

 public class BinarySearchTree<T extends Comparable<T>> 

Ένα τυπικό επιχείρημα γενόσημα φάρμακα, σε περίπτωση που σας T, παραθέτει ό, τι απαιτείται για μια κατηγορία να είναι μια έγκυρη Τ Σε περίπτωση που, έχετε πει, «για να είναι έγκυρη T, μια κατηγορία πρέπει να εφαρμόσει Συγκρίσιμα» (Η λέξη-κλειδί είναι «επεκτείνεται », αλλά στην πράξη αυτό σημαίνει“εκτείνεται ή εργαλείων”.)

Στο στιγμιότυπο σας, T είναι φοιτητής. Αν αντικαταστήσουμε Φοιτητών για την T:

public class BinarySearchTree<Student extends Comparable<Student>>

είναι ότι μια αληθινή δήλωση; Μήπως Φοιτητής πραγματικά να εφαρμόσουν συγκρίσιμα;

Αν το κάνει, Φοιτητής ταιριάζει με την προϋπόθεση της ύπαρξης ενός Τ, και έτσι μπορείτε να χρησιμοποιήσετε σπουδαστών ως πραγματική παράμετρο για την επίσημη Τ παράμετρο

Αν όχι, μπορείτε να πάρετε το παράπονο του μεταγλωττιστή που είδατε.

Στην πραγματικότητα, για να καλύψει τις πιο περίπλοκες καταστάσεις όπου η εφαρμογή μιας υποκατηγορίας των Συγκρίσιμα γίνεται από ένα σούπερ τάξη, η πιο γενική μορφή θα είναι:

   public class BinarySearchTree<T extends Comparable<? super T > > 

Έτσι πρέπει να κάνουμε Φοιτητική εφαρμογή Συγκρίσιμα <Φοιτητών>.

Σημειώστε ότι εγώ δεν έλεγα ότι ο μεταφραστής ψάχνει για έναν Student.compareTo. Δεν έχει καν πάρει τόσο μακριά. Είναι ψάχνει να δει αν T (στην περίπτωσή σας, Φοιτητής) έχει χαρακτηριστεί ως εφαρμογή Συγκρίσιμα <T> (στην περίπτωσή σας, Συγκρίσιμα <Φοιτητής>).

Τώρα προσθήκη implements Comparable< Student >στο Φοιτητικό θα επίσης κάνει ο compiler διασφαλίσει ότι υπάρχει μια public int compareToμέθοδος για Student. Αλλά χωρίς το «υλοποιεί συγκρίσιμα», ακόμη και αν ο compiler ξέρει ότι υπάρχει μια μέθοδος Student.compareTo, δεν ξέρουν ότι αυτό compareToείναι το Comparable.compareTo.

(Με άλλα λόγια, ψάχνουμε για δηλώνονται εφαρμογή, όχι μόνο ότι συμβαίνει να είναι μια μέθοδος με το σωστό όνομα και την υπογραφή εκεί.)

Απαντήθηκε 02/05/2009 στις 06:57
πηγή χρήστη

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