Java Generisk binært søketre typen problem

stemmer
1

Jeg jobber med dette lekser som er slags forvirrende meg ...

Jeg er utstyrt med følgende BinarySearchTree klassen

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);
    }
}

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

Nå har jeg en annen klasse Student .... Jeg ønsker å lage et binært søketre av Student gjenstander ..

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

Men når jeg gjør det får jeg følgende feilmelding:

Bundet mismatch: Typen Student ikke er en gyldig erstatning for det avgrensede parameter> av den type som BinarySearchTree

Noen ideer hva som skjer her ... Jeg kan ikke finne ut av det.

Publisert på 02/05/2009 klokken 05:31
kilden bruker
På andre språk...                            


3 svar

stemmer
0

Har klassen Student gjennomføre Sammenlign?

Svarte 02/05/2009 kl. 05:41
kilden bruker

stemmer
0

men jeg er ikke helt sikker på hvordan å implementere compareTo-metoden.

I utgangspunktet er det noe sånt som følgende. Hvordan bestiller fungerer du må bestemme.

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
    }
}
Svarte 02/05/2009 kl. 05:56
kilden bruker

stemmer
6

 public class BinarySearchTree<T extends Comparable<T>> 

En formell generika argument, i ditt tilfelle T, viser hva som kreves for en klasse til å være en gyldig T. I du fall har du sa, "for å være en gyldig T, en klasse må implementere Sammenlign" (Nøkkelordet er "strekker ", men i praksis som betyr 'utvider eller implementerer').

I oppretting, er T Student. Hvis vi erstatte Student for T:

public class BinarySearchTree<Student extends Comparable<Student>>

er at et sant utsagn? Har Student virkelig gjennomføre Sammenlign?

Hvis den gjør det, passer Student kravet om å være en T, og slik at du kan bruke Student som selve parameter for den formelle parameteren T.

Hvis ikke, får du kompilatoren klage du så.

Egentlig, for å dekke mer kompliserte situasjoner hvor en underklasse gjennomføring av tilsvarende gjøres av en super klasse, ville den mer generelle form være:

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

Så du trenger å gjøre Student implementere Comparable <Student>.

Merk at jeg ikke sier at kompilatoren er på jakt etter en Student.compareTo. Det trenger ikke engang kommer så langt. Det ser for å se om T (i ditt tilfelle, Student) er erklært som implementerer Comparable <T> (i ditt tilfelle, Sammenlign <Student>).

Nå legger implements Comparable< Student >til Student vil også gjøre kompilatoren sørge for at det er en public int compareTometode på Student. Men uten "implementerer Comparable", selv om kompilatoren vet at det er en metode Student.compareTo, betyr det ikke at det compareToer det Comparable.compareTo.

(Med andre ord, vi leter etter erklærte gjennomføring, ikke bare at det skjer for å være en metode med riktig navn og signatur.)

Svarte 02/05/2009 kl. 05:57
kilden bruker

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