Java Generic Binary Search Tree soort probleem

stemmen
1

Ik ben bezig met dit huiswerk dat me soort verwart ...

Ik ben voorzien van de volgende BinarySearchTree klasse

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

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

Nu heb ik een andere klasse Student .... Ik wil een binaire zoekboom van Student objecten te creëren ..

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

Maar wanneer ik dat doe krijg ik de volgende foutmelding:

Bound mismatch: Het type Student is geen geldig substituut voor de begrensde parameter> van het type BinarySearchTree

Enig idee wat hier gebeurt ... Ik kan er niet uit.

De vraag is gesteld op 02/05/2009 om 06:31
bron van user
In andere talen...                            


3 antwoorden

stemmen
0

Heeft de klasse Student implementeren Vergelijkbare?

antwoordde op 02/05/2009 om 06:41
bron van user

stemmen
0

maar ik ben niet helemaal zeker hoe het compareTo methode te implementeren.

Eigenlijk is het iets als het volgende. Hoe het bestelproces werkt je moet beslissen.

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
    }
}
antwoordde op 02/05/2009 om 06:56
bron van user

stemmen
6

 public class BinarySearchTree<T extends Comparable<T>> 

Een formele generics argument, in uw geval T, laat zien wat er nodig is voor een klasse om een ​​geldig T. in u het geval, u hebt gezegd, "om een ​​geldige T, een klasse moet Vergelijkbaar implementeren" (Het sleutelwoord is "strekt ", maar in de praktijk betekent 'omvatten of werktuigen').

In je instantiatie, T is Student. Als we vervangen door Student voor T:

public class BinarySearchTree<Student extends Comparable<Student>>

is dat een ware uitspraak? Heeft Student echt implementeren Vergelijkbare?

Als dat zo is, Student past bij de eis dat een T, en dus kun je Student gebruiken als de werkelijke parameter voor de formele parameter T.

Zo niet, dan krijg je de klacht van de compiler je zag.

Eigenlijk, om meer gecompliceerde situaties waarin de uitvoering van vergelijkbare een subklasse's wordt gedaan door een super klasse te dekken, zou de meer algemene vorm:

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

Dus moet u ervoor Student implementeren Vergelijkbaar <Student>.

Merk op dat ik niet zeggen dat de compiler is op zoek naar een Student.compareTo. Het maakt niet eens zo ver. Het is op zoek om te zien of T (in uw geval, Student) wordt als de uitvoering verklaard Vergelijkbaar <T> (in uw geval, Vergelijkbaar <Student>).

Nu is het toevoegen van implements Comparable< Student >Student zal ook maken de compiler ervoor te zorgen dat er een public int compareTomethode op Student. Maar zonder de "implementeert Vergelijkbaar", zelfs als de compiler weet dat er een methode Student.compareTo, maar weet niet dat dat compareTois het Comparable.compareTo.

(Met andere woorden, zijn wij op zoek voor de opgegeven uitvoering, niet alleen dat er toevallig een methode met de juiste naam en handtekening te zijn.)

antwoordde op 02/05/2009 om 06:57
bron van user

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