240 likes | 361 Views
Dictionnaire. On veut une structure permettant d’insérer, d’enlever et de rechercher des enregistrements. Concepts importants: Clef de recherche: Décrit ce que nous recherchons. Clef de comparaison Égalité: recherche séquentielle Ordre total: tri Comparaison d’enregistrements. Exemple (1).
E N D
Dictionnaire On veut une structure permettant d’insérer, d’enlever et de rechercher des enregistrements. Concepts importants: • Clef de recherche: Décrit ce que nous recherchons. • Clef de comparaison • Égalité: recherche séquentielle • Ordre total: tri • Comparaison d’enregistrements
Exemple (1) Class Dossier{ public: int ID; char* nom; }; class IDCompare { public: bool lt(Dossier& x, Dossier& y) { return x.ID < y.ID; } bool eq(Dossier& x, Dossier& y) { return x.ID == y.ID; } bool gt(Dossier& x, Payroll& y) { return x.ID > y.ID; } };
Exemple (2) class NomCompare { public: bool lt(Dossier& x, Dossier& y) { return strcmp(x.nom, y.nom) < 0; } bool eq(Dossier& x, Dossier& y) { return strcmp(x.nom, y.nom) == 0; } bool gt(Dossier& x, Dossier& y) { return strcmp(x.nom, y.nom) > 0; } };
Exemple (3) class NDCompare { public: bool lt(char* x, Dossier& y) { return strcmp(x, y.nom) < 0; } bool eq(char* x, Dossier& y) { return strcmp(x, y.nom) == 0; } bool gt(char* x, Dossier& y) { return strcmp(x, y.nom) > 0; } };
Dictionnaire: classe abstraite // Classe abstraite pour le dictionnaire. template <class Key, class Elem, class KEComp, class EEComp> class Dictionary { public: virtual void clear() = 0; virtual bool insert(const Elem&) = 0; virtual bool remove(const Key&, Elem&) = 0; virtual bool find(const Key&, Elem&) const = 0; virtual int size() = 0; };
Dictictionnaire: liste non triée template <class Key, class Elem, class KEComp, class EEComp> class UALdict : public Dictionary<Key,Elem,KEComp,EEComp> { private: AList<Elem>* list; public: UALdict(int size=DefaultListSize) {list = new AList<Elem>(size); } ~UALdict() { delete list; } void clear() { list->clear(); }
Dictictionnaire: liste non triée bool insert(const Elem& e) { return list->append(e); } bool remove(const Key& K, Elem& e) { for(list->setStart(); list->getValue(e); list->next()) if (KEComp::eq(K, e)) { list->remove(e); return true; } return false; } };
Dictictionnaire: liste non triée bool find(const Key& K, Elem& e) const { for(list->setStart(); list->getValue(e); list->next()) if (KEComp::eq(K, e)) return true; return false; } int size() {return list->leftLength() + list->rightLength(); } };
Coût des opérations ChercherAjouterEnlever Liste non triée: O(n) O(1) O(1) Liste trié : O(n) O(n) O(1) Tableau non trié: O(n) O(1) O(n) Tableau trié: O(lg n) O(n) O(n)
Arbres binaires de recherche Propriétés des ABR: Soit N, un nœud de valeur K. • Tous les éléments stockés dans le sous-arbre de gauche de N ont une valeur < K. • Tous les éléments stockés dans le sous-arbre de droite de N ont une valeur K.
ABR: implémentation (1) template <class Key, class Elem, class KEComp, class EEComp> class BST : public Dictionary<Key, Elem, KEComp, EEComp> { private: BinNode<Elem>* root; // Racine int nodecount; // Nombre de noeuds void clearhelp(BinNode<Elem>*); BinNode<Elem>* inserthelp(BinNode<Elem>*, const Elem&);
ABR: implémentation (2) BinNode<Elem>* deletemin(BinNode<Elem>*, BinNode<Elem>*&); BinNode<Elem>* removehelp(BinNode<Elem>*, const Key&, BinNode<Elem>*&); bool findhelp(BinNode<Elem>*, const Key&, Elem&) const; void printhelp(BinNode<Elem>*, int) const;
ABR: implémentation (3) public: BST() { root = NULL; nodecount = 0; } ~BST() { clearhelp(root); } void clear() { clearhelp(root); root = NULL; nodecount = 0; } bool insert(const Elem& e) { root = inserthelp(root, e); nodecount++; return true; }
ABR: implémentation (4) bool remove(const Key& K, Elem& e) { BinNode<Elem>* t = NULL; root = removehelp(root, K, t); if (t == NULL) return false; e = t->val(); nodecount--; delete t; return true; }
ABR: implémentation (5) bool removeAny(Elem& e) { // Delete min value if (root == NULL) return false; // Empty BinNode<Elem>* t; root = deletemin(root, t); e = t->val(); delete t; nodecount--; return true; }
ABR: implémentation (6) bool find(const Key& K, Elem& e) const { return findhelp(root, K, e); } int size() { return nodecount; } void print() const { if (root == NULL) cout << ”L’arbre est vide.\n"; else printhelp(root, 0); } };
ABR: rercherche template <class Key, class Elem, class KEComp, class EEComp> bool BST<Key, Elem, KEComp, EEComp>:: findhelp(BinNode<Elem>* subroot, const Key& K, Elem& e) const { if (subroot == NULL) return false; else if (KEComp::lt(K, subroot->val())) return findhelp(subroot->left(), K, e); else if (KEComp::gt(K, subroot->val())) return findhelp(subroot->right(), K, e); else { e = subroot->val(); return true; } }
ABR: insérer(2) template <class Key, class Elem, class KEComp, class EEComp> BinNode<Elem>* BST<Key,Elem,KEComp,EEComp>:: inserthelp(BinNode<Elem>* subroot, const Elem& val) { if (subroot == NULL) return new BinNodePtr<Elem>(val,NULL,NULL); if (EEComp::lt(val, subroot->val())) subroot->setLeft(inserthelp(subroot->left(), val)); else subroot->setRight( inserthelp(subroot->right(), val)); return subroot; }
Enlever la plus petite valeur template <class Key, class Elem, class KEComp, class EEComp> BinNode<Elem>* BST<Key,Elem,KEComp, EEComp>:: deletemin(BinNode<Elem>* subroot, BinNode<Elem>*& min) { if (subroot->left() == NULL) { min = subroot; return subroot->right(); } else { subroot->setLeft( deletemin(subroot->left(), min)); return subroot; } }
ABR: enlever (2) template <class Key, class Elem, class KEComp, class EEComp> BinNode<Elem>* BST<Key,Elem,KEComp,EEComp>:: removehelp(BinNode<Elem>* subroot, const Key& K, BinNode<Elem>*& t) { if (subroot == NULL) return NULL; else if (KEComp::lt(K, subroot->val())) subroot->setLeft( removehelp(subroot->left(), K, t)); else if (KEComp::gt(K, subroot->val())) subroot->setRight( removehelp(subroot->right(), K, t));
ABR: enlever (3) else { // L’élément est trouvé BinNode<Elem>* temp; t = subroot; if (subroot->left() == NULL) subroot = subroot->right(); else if (subroot->right() == NULL) subroot = subroot->left(); else { // Les deux fils sont non vides subroot->setRight( deletemin(subroot->right(), temp)); Elem te = subroot->val(); subroot->setVal(temp->val()); temp->setVal(te); t = temp; } } return subroot; }
Coût des opérations Arbre balancéArbre non balancé Trouver: O(lg n) O(n) Insérer: O(lg n) O(n) Enlever: O(lg n) O(n)