Problém typu Java Generic Binární vyhledávací strom

hlasů
1

Pracuji na tomto úkoly, které mě trochu matoucí ...

Jsem za předpokladu, s následující třídy 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);
    }
}

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

Teď mám další třídu Student .... chci vytvořit strom binárního vyhledávání objektů Student ..

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

Nicméně když jsem si, že jsem si následující chybu:

Vázaný Neshoda: Typ Student není platný náhradou za ohraničené parametru> typového BinarySearchTree

Nějaké nápady, co se tady děje ... Nemohu na to přijít.

Položena 02/05/2009 v 06:31
zdroj uživatelem
V jiných jazycích...                            


3 odpovědí

hlasů
0

Má třída Student zavést srovnatelné?

Odpovězeno 02/05/2009 v 06:41
zdroj uživatelem

hlasů
0

ale nejsem si úplně jistý, jak implementovat metodu CompareTo.

V podstatě je to něco jako následující. Jak uspořádání funguje musíte rozhodnout.

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
    }
}
Odpovězeno 02/05/2009 v 06:56
zdroj uživatelem

hlasů
6

 public class BinarySearchTree<T extends Comparable<T>> 

Formální generika argument v případě T, uvádí, co je požadováno pro třídu být platný T. ve vás případě jsem vám řekl: „být platný T, třída musí implementovat Srovnatelné“ (Klíčové slovo je „rozšiřuje “, ale v praxi to znamená, že‚se vztahuje nebo nářadí‘).

Ve vaší instance, T je Student. Dosadíme-li student u T:

public class BinarySearchTree<Student extends Comparable<Student>>

je to, že skutečný prohlášení? Má Student skutečně realizovat srovnatelné?

Pokud k tomu dojde, Student odpovídá požadavku bytí T, a proto můžete použít Student jako aktuální parametr pro formální parametr T.

Pokud tomu tak není, dostanete stížnost kompilátoru jste viděli.

Ve skutečnosti, na pokrytí složitější situace, kdy realizace podtřídy je srovnatelných se provádí super třídě, obecnější forma bude vypadat následovně:

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

Takže je potřeba, aby se student realizovat Srovnatelné <Student>.

Všimněte si, že jsem neměl říkat, že kompilátor je hledal Student.compareTo. To není ani tak daleko. Vypadá to, aby zjistili, zda T (v případě studenta) je deklarována jako prováděcí Srovnatelné <T> (v případě Srovnatelné <Student>).

Nyní přidává implements Comparable< Student >k Student bude také , aby kompilátor zajistí, že tam je public int compareTometoda na studenta. Ale bez „implementuje Srovnatelné“, a to i v případě, že kompilátor ví, že je to způsob Student.compareTo, neví, že compareToje Comparable.compareTo.

(Jinými slovy, hledáme deklarované realizaci, a to nejen, že se stane, že metoda se správným jménem a podpisem).

Odpovězeno 02/05/2009 v 06:57
zdroj uživatelem

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