Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 14
  1. #1

    [Java] Parente di un nodo in BST

    Salve a tutti, ho un piccolo problema. Sono faccia a faccia con un dizionario implementato con alberi binari di ricerca dove ogni nodo NON ha il riferimento al nodo genitore. Questo mi sta creando non poche difficoltà. E' possibile costruire un
    algoritmo che avendo in input la radice ed il nodo del quale interessa trovare il genitore, restituisce appunto il genitore di
    questo nodo?

  2. #2

    Re: [Java] Parente di un nodo in BST

    Originariamente inviato da Javino89
    Salve a tutti, ho un piccolo problema. Sono faccia a faccia con un dizionario implementato con alberi binari di ricerca dove ogni nodo NON ha il riferimento al nodo genitore. Questo mi sta creando non poche difficoltà. E' possibile costruire un
    algoritmo che avendo in input la radice ed il nodo del quale interessa trovare il genitore, restituisce appunto il genitore di
    questo nodo?
    Si. La cosa è piuttosto banale.

  3. #3
    Ok, appurato che non è una scemenza... ho inziato a scrivere questo:

    codice:
    private BSTNode findParentRic(BSTNode root, BSTNode v)
            {
                if(root.getKey() < v.getKey())
                {
                    BSTNode d = root.getRight();
                    if(d.getKey() == v.getKey() && d.getValue().equals(v.getValue()))
                    {
                        return root;
                    }
                    return findParentRic(d,v);
                }
                else if(root.getKey() > v.getKey())
                {
                    BSTNode s = root.getLeft();
                    if(s.getKey() == v.getKey() && s.getValue().equals(v.getValue()))
                    {
                        return root;
                    }
                    return findParentRic(s,v);
                }
                else
                    //???
            }

  4. #4
    Originariamente inviato da Javino89
    Ok, appurato che non è una scemenza...
    Se vuoi un vero aiuto devi specificare come è strutturato il dizionario, l'albero binario incapsulato, la segnatura dell'operatore che intendi implementare.

    Poi domanda: l'operatore serve a restituire il valore di una data chiave o viceversa oppure altro scopo? L'albero binario quale funzionalità assume esattamente?

  5. #5
    Classe Nodo:

    codice:
    /**
     * Classe node per un BST che contiene la chiave di tipo intero e un valore di tipo String.
     * 
    
     * Si richiede che per ogni nodo la sua chiave sia strettamente maggiore di quelle memorizzate
     * nel sottoalbero sinistro e minore o uguale di quelli nel sottoalbero destro.
     * 
    
    Come conseguenza di cio' i valori con chiave duplicata devono essere inseriti nel ramo destro.
     */
    public final class BSTNode {
        private int key;
        private String value;
        private BSTNode left;
        private BSTNode right;
    
        /**
         * costruisce un nodo vuoto
         */
        public BSTNode() {
        }
    
        /**
         * ritorna la chiave
         *
         * @return chiave
         */
        public int getKey() {
            return key;
        }
    
        /**
         * imposta il valore della chiave
         *
         * @param key chiave
         */
        public void setKey(int key) {
            this.key = key;
        }
    
        /**
         * restutisce il sottoalbero sinistro
         *
         * @return sottoalbero sinistro o null se non presente
         */
        public BSTNode getLeft() {
            return left;
        }
    
        /**
         * imposta il valore del sottoalbero sinistro
         *
         * @param left sottoalbero sinistro
         */
        public void setLeft(BSTNode left) {
            this.left = left;
        }
    
        /**
         * restituisce il riferimento al sottoalbero destro
         *
         * @return sottoalbero destro o null se non presente
         */
        public BSTNode getRight() {
            return right;
        }
    
        /**
         * imposta il riferimento al sottoalbero destro
         *
         * @param right sottoalbero destro
         */
        public void setRight(BSTNode right) {
            this.right = right;
        }
    
        /**
         * ritorna il valore associato al nodo
         *
         * @return valore associato al nodo
         */
        public String getValue() {
            return value;
        }
    
        /**
         * imposta il valore associato al nodo
         *
         * @param value valore da impostare
         */
        public void setValue(String value) {
            this.value = value;
        }
    
        @Override
        public String toString() {
            return "<" + key + "=" + value + ">";
        }
    }
    Interfaccia Dizionario

    codice:
    import java.util.*;
    
    /**
     * Interfaccia di un BST che implementa un dizionario contenente coppie chiave valore rispettivamente di tipo intero e String.
     * Il dizionario deve ammettere chiavi multiple.
     * Nel BST i valori duplicati devono essere inseriti nell'albero destro.
     */
    public interface BSTDictionary {
        /**
         * a partire dalla chiave intera, viene restituito il valore associato. Se la chiave non fa parte del BST allora rescituisce null.
         * Nel caso in cui siano presenti piu' chiavi uguali, deve restituire uno qualunque dei valori.
         *
         * @param key chiave
         * @return valore associato alla chiave oppure null se la chiave non fa parte del dizionario.
         */
        public String find(int key);
    
        /**
         * restituisce tutti i valori associati alla chiave. Se la chiave non e' presente, resituisce null.
         *
         * @param key chiave
         * @return elenco dei valori associati alla chiave
         */
        public List<String> findAll(int key);
    
        /**
         * inserisce una nuova coppia chiave valore, da aggiungere al dizionario.
         * Si ricorda che il dizionario ammette duplicati.
         *
         * @param key   chiave
         * @param value valore
         */
        public void insert(int key, String value);
    
        /**
         * controlla se l'albero e' vuoto (cioe' ha radice nulla)
         *
         * @return true o false a seconda se l'albero e' vuoto o no
         */
        public boolean isEmpty();
    
        /**
         * restituisce la radice dell'albero
         *
         * @return radice dell'albero o null se l'albero e' vuoto
         */
        public BSTNode root();
    
        /**
         * ritorna il numero di nodi dell'albero
         *
         * @return numero di nodi dell'albero
         */
        public int size();
    
        /**
         * rimuove tutte le chiavi dell'albero strettamente maggiori della chiave specificata.
         * Il metodo deve effettuare side - effect sui nodi dell'albero this.
         * @param key chiave specificata
         */
        public void removeHigh(int key);
    }
    codice:
    import java.util.*;
    
    /**
     * Questa classe deve essere implementata per poter risolvere l'homework
     * Si ricorda che il nome della classe deve essere Homework5Impl e non deve essere
     */
    public abstract class Homework5 {
        /**
         * le sottoclassi dovranno avere un solo costruttore senza argomenti
         */
        public Homework5() {
            if (getClass().getConstructors().length != 1) {
                throw new RuntimeException(String.format(
                        "ATTENZIONE!!! La sottoclasse deve avere solo il costrutture senza argomenti. Trovati %d costruttori",
                        getClass().getConstructors().length));
            }
            if (getClass().getConstructors()[0].getParameterTypes().length > 0)
                throw new RuntimeException(String.format(
                        "ATTENZIONE!!! La sottoclasse deve avere solo il costrutture senza argomenti. Trovato un costruttore con %d argomenti",
                        getClass().getConstructors().length));
            if (!getClass().getSimpleName().equals("Homework5Impl") &&
                    !getClass().getSimpleName().equals("Homework5ImplSolver")) {
                throw new RuntimeException("ATTENZIONE!!! La sottoclasse deve avere nome Homework5Impl");
            }
            if (getClass().getPackage() != null) {
                throw new RuntimeException("ATTENZIONE!!! La sottoclasse non deve appartenere ad alcun PACKAGE");
            }
        }
    
        /**
         * restituisce un nuovo dizionario vuoto
         *
         * @return restituisce un nuovo dizionario vuoto
         */
        public abstract BSTDictionary createEmptyDictionary();
    
        /**
         * restituisce tutte le chiavi comuni ai due dizionari. In caso di duplicati restituire un unico valore per la chiave.
         *  Il metodo dovra' avere costo lineare rispetto al numero di nodi.
         *
         * @param d1 primo dizionario
         * @param d2 secondo dizionario
         * @return chiavi comuni ad entrambi i dizionari
         */
        public abstract Set<Integer> commonKeys(BSTDictionary d1, BSTDictionary d2);
    }
    Queste sono classi già fornite, io devo realizzare questa:

    codice:
    import java.util.*;
    
    public class Homework5Impl extends Homework5
    {
        public Homework5Impl() {}
    
        class BSTDictionaryImpl implements BSTDictionary
        {
            private BSTNode root;
    
            public BSTDictionaryImpl()
            {
                root = null;
            }
    
            //Ritorna l'elemento del nodo con chiave key
            public String find(int key)
            {
                return findRic(key,root);
            }
    
            private String findRic(int k, BSTNode v)
            {
                if(isExternal(v))
                {
                    return v.getValue();
                }
                if(k < v.getKey())
                {
                    return findRic(k, v.getLeft());
                }
    
                else if(k == v.getKey())
                {
                    return v.getValue();
                }
                else
                {
                    return findRic(k, v.getRight());
                }
            }
    
            //Ritorna il nodo che ha la stessa chiave passata come parametro
            private BSTNode treeSearch(int k, BSTNode v)
            {
                if(isExternal(v))
                {
                    return v;
                }
    
                if(k < v.getKey())
                {
                    return treeSearch(k, v.getLeft());
                }
    
                else if(k == v.getKey())
                {
                    return v;
                }
    
                else
                {
                    return treeSearch(k, v.getRight());
                }
            }
    
            private boolean isExternal(BSTNode v)
            {
                return ((v.getLeft() == null) && (v.getRight()==null));
            }
    
            public List<String> findAll(int key)
            {
                List<String> ris = new LinkedList<String>();
                addAll(ris,root,key);
                return ris;
            }
    
            private void addAll(List<String> L, BSTNode v, int key)
            {
                if(isExternal(v))
                {
                    return;
                }
    
                BSTNode pos = treeSearch(key, v);
    
                if(!isExternal(pos))
                {
                    addAll(L,pos.getLeft(),key);
                    L.add(L.size()-1, pos.getValue());
                    addAll(L,pos.getRight(),key);
                }
            }
    
            public void insert(int key, String value)
            {
                BSTNode toInsert = new BSTNode();
                toInsert.setKey(key);
                toInsert.setValue(value);
                insert(key,value,toInsert);
            }
    
            private void insert(int key, String value, BSTNode v)
            {
                BSTNode w = treeSearch(key,v);
    
                if(!isExternal(w))
                {
                    insert(key,value,w.getRight());
                }
    
                insertAtExternal(w,key,value);
            }
    
            private void insertAtExternal(BSTNode v, int key, String value)
            {
                v.setKey(key);
                v.setValue(value);
                v.setLeft(new BSTNode());
                v.setRight(new BSTNode());
            }
    
            public boolean isEmpty()
            {
                return this.root == null;
            }
    
            public BSTNode root()
            {
                return this.root;
            }
    
            public int size()
            {
                if(root == null)
                {
                    return 0;
                }
                else return sizeRic(root,1);
            }
    
            private int sizeRic(BSTNode v, int s)
            {
                if(v.getLeft() != null)
                {
                    s = 1 + sizeRic(v.getLeft(),s);
                }
                if(v.getRight() != null)
                {
                    s = 1 + sizeRic(v.getRight(),s);
                }
                return s;
            }
    
            private BSTNode findParent(BSTNode v)
            {
                return findParentRic(this.root, v);
            }
    
            private BSTNode findParentRic(BSTNode root, BSTNode v)  <--- QUI MI SERVE AIUTO
            {
                
                if(root.getKey() < v.getKey())
                {
                    BSTNode d = root.getRight();
                    if(d.getKey() == v.getKey() && d.getValue().equals(v.getValue()))
                    {
                        return root;
                    }
                    return findParentRic(d,v);
                }
                else if(root.getKey() > v.getKey())
                {
                    BSTNode s = root.getLeft();
                    if(s.getKey() == v.getKey() && s.getValue().equals(v.getValue()))
                    {
                        return root;
                    }
                    return findParentRic(s,v);
                }
                else
                    return null;
            }
    
            private void removeExternal(BSTNode v)
            {
                .....
            }
    
            public void remove(int key)
            {
                .....
            }
    
            public void removeHigh(int key)
            {
                
            }
        }
    
        /*Il metodo restituisce un nuovo dizionario inizialmente vuoto. Il metodo
        al suo interno potra' utilizzare la classe BSTDictionaryImpl descritta
        nella successiva sotto-sezione.*/
    
        public BSTDictionary createEmptyDictionary()
        {
            BSTDictionary ris = new BSTDictionaryImpl();
            return ris;
        }
    
        /*Il metodo restituisce l'insieme delle chiavi comuni ai due dizionari. In
        caso di chiavi duplicate in uno o entrambi i dizionari deve restituire un
        unico valore per la chiave.
        Il metodo dovra' avere costo lineare rispetto al massimo tra
        le dimensioni dei due dizionari.*/
    
        public Set<Integer> commonKeys(BSTDictionary d1, BSTDictionary d2)
        {
                 ..........
        }
    }

  6. #6
    Bene. Ti serve salvare i nodi che stai visitando in una vera e propria pila.

    Qualcosina dell'algoritmo:
    quando vai ad inpilare i figli del k-esimo nodo estratto dalla pila (chiamando su di esso getLeft() e getRight()):
    se uno dei due è uguale a v allora suo padre è il top della pila, ovvero l'elemento appena estratto.

    Come ti dicevo è una banalità.

  7. #7
    Una pila? :S Io preferirei usare la ricorsione per abituarmici... ti ho già incollato quel po che ho scritto, ma non so se può andare e manca una parte.

  8. #8
    Originariamente inviato da Javino89
    Ho scritto quello che hai visto.. è giusto? E' da completare però..
    Si ho letto e non va per nulla bene.

    Inoltre
    codice:
    d.getKey() == v.getKey() && d.getValue().equals(v.getValue())
    può andare bene, ma poichè programmi in Java questi controlli sono da delegare ad una ridefinizione del metodo equals() all'interno della classe BSTNode.

    Originariamente inviato da Javino89
    Oddio fe, come una pila xD
    Presumo tu stia seguendo un corso di Algoritmi e Strutture dati, quindi devi sapere cos'è una pila.

    Originariamente inviato da Javino89
    l'equivalente ricorsivo come sarebbe?
    Ci arrivi da solo senza complicazioni se implementi prima la soluzione iterativa.

  9. #9
    Si si, so cos'è una pila, ma all'esame vengono chiesti solo metodi ricorsivi, e per la storia della ridefinizione di equals, non posso modificare le classi che ci ha fornito il professore.

    Se in input ho radice più nodo di cui devo sapere il genitore (nodo v ad esempio),il mio ragionamento ricorsivo era:

    Se v ha chiave maggiore della radice, allora il genitore di v si trova nel sottoalbero destro della radice e controllo
    che non sia proprio il figlio destro della radice ad essere v stesso, in tal caso torni la radice, altrimenti chiami
    ricorsivamente il metodo su figlio destro della radice.
    Se poi v ha chiave minore della radice il suo genitore deve stare per forza nel sottoalbero sinistro della radice e fai
    lo stesso ragionamento di prima..
    l'else sarebbe che le chiavi dei due nodi sono uguali ma non so come comportarmi in tal caso...

  10. #10
    Originariamente inviato da Javino89
    il mio ragionamento ricorsivo
    Non si tratta di un ragionamento ricorsivo ma di una soluzione!
    POI questa soluzione può essere implementata in modo iterativo oppure ricorsivo, quindi non è detto che sia per forza ricorsiva!


    Originariamente inviato da Javino89
    Se v ha chiave maggiore della radice, allora il genitore di v si trova nel sottoalbero destro della radice
    E questo chi lo garantisce? Se ti è stato fornito un requisito che specifica ciò, allora va bene; altrimenti è assolutamente sbagliato.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.