Java générique binaire de type Recherche question Arbre

voix
1

Je travaille sur ce travail à domicile qui est une sorte de me confondre ...

Je suis fourni avec la classe BinarySearchTree suivante

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

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

Maintenant, j'ai un autre étudiant de classe .... Je veux créer un arbre de recherche binaire d'objets étudiants ..

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

Mais quand je fais ce que je reçois l'erreur suivante:

disparité liée: L'étudiant type ne remplace pas valide pour le paramètre borné> du type BinarySearchTree

Toutes les idées ce qui se passe ici ... Je ne peux pas comprendre.

Créé 02/05/2009 à 06:31
source utilisateur
Dans d'autres langues...                            


3 réponses

voix
0

La mise en œuvre des élèves de la classe Comparable?

Créé 02/05/2009 à 06:41
source utilisateur

voix
0

mais je ne suis pas tout à fait sûr de savoir comment mettre en œuvre la méthode compareTo.

Fondamentalement, il est quelque chose comme ce qui suit. Comment fonctionne la commande que vous devez décider.

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
    }
}
Créé 02/05/2009 à 06:56
source utilisateur

voix
6

 public class BinarySearchTree<T extends Comparable<T>> 

Un argument formel des médicaments génériques, dans votre cas T, énumère ce qui est nécessaire pour qu'une classe soit un T. valide En vous cas, vous avez dit, « être un T, une classe valide doit mettre en œuvre Comparable » (Le mot-clé est « étend », mais dans la pratique, cela signifie « étend ou met en œuvre ».)

Dans votre instanciation, T est étudiant. Si l'on remplace l'étudiant T:

public class BinarySearchTree<Student extends Comparable<Student>>

est ce une vraie déclaration? Est-ce que l'élève vraiment mettre en œuvre Comparable?

Dans le cas contraire, l'élève correspond à l'exigence d'être un T, et vous pouvez donc utiliser l'étudiant comme paramètre réel pour le paramètre formel T.

Sinon, vous obtenez la plainte du compilateur que vous avez vu.

En fait, pour couvrir des situations plus complexes où la mise en œuvre d'une sous-classe de Comparable est fait par une super classe, la forme plus générale serait la suivante:

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

Donc, vous devez vous mettre en œuvre des étudiants Comparable <étudiant>.

Notez que je ne l' ai pas dit que cherche le compilateur a Student.compareTo. Il n'a même pas obtenir loin. Il cherche à voir si T (dans votre cas, l' étudiant) est déclarée comme la mise en œuvre Comparable <T> (dans votre cas, Comparable <étudiant>).

Maintenant , en ajoutant implements Comparable< Student >à l' étudiant sera également faire le compilateur d' assurer qu'il ya une public int compareTométhode sur l' élève. Mais sans « implémente Comparable », même si le compilateur sait qu'il ya une méthode Student.compareTo, il ne sait pas que compareToc'est le Comparable.compareTo.

(En d'autres termes, nous sommes à la recherche de mise en œuvre déclarée, non seulement qu'il y arrive d'être une méthode avec le bon nom et signature.)

Créé 02/05/2009 à 06:57
source utilisateur

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