920 likes | 1.13k Views
Université Paris XI I.U.T. d'Orsay Département Informatique Année scolaire 2003-2004. Algorithmique : Volume 6 Recherche Adressage dispersé Tris Complexité . Cécile Balkanski, Nelly Bensimon, Gérard Ligozat. Recherche. Recherche .
E N D
Université Paris XII.U.T. d'OrsayDépartement InformatiqueAnnée scolaire 2003-2004 Algorithmique : Volume 6 • Recherche • Adressage dispersé • Tris • Complexité Cécile Balkanski, Nelly Bensimon, Gérard Ligozat
Recherche Algorithmique 6 : Recherche, complexité, tris
Recherche • Problème général abstrait ensemble de valeurs E, élément a; est‑ce que a E? réponse: booléen (x) { xE | x=a } • plus généralement existe‑t‑il x vérifiant certains critères (x) { xE | j(x)} trouver tous les x satisfaisant certains critères { xE | j(x)} (bases de données) Algorithmique 6 : Recherche, complexité, tris
Recherche en informatique • On ne travaille pas sur des ensembles mathématiques, mais sur des structures de données particulières • Les données peuvent être de nature complexe (agrégats, classes) • Exemples : tableau tableau trié Algorithmique 6 : Recherche, complexité, tris
arbre binaire de recherche 20 24 18 27 9 19 32 5 13 2 36 15 8 12 17 7 Algorithmique 6 : Recherche, complexité, tris
Tri de données complexes • Exemple de donnée complexe: type Etudiant = agrégat nom: chaîne âge: entier classement: entier photo: fichier_GIF fin • on peut trier par nom (ordre alphabétique), par âge, par classement • pas par photo • clés, clés primaires ex‑aequo, même âge Algorithmique 6 : Recherche, complexité, tris
Recherche et type de données • On utilise divers types de données sur lesquelles on fait des opérations de base: • ajout • suppression • mise‑à jour • consultation • Chaque structure a des avantages et des inconvénients : • tableau, tableau trié, arbre binaire, liste chaînée, etc. Algorithmique 6 : Recherche, complexité, tris
Recherche séquentielle fonction rechSeq (tab , nbre , val) retourne (booléen) {renvoie VRAI si val est dans tab, FAUX sinon} paramètre s (D) tab: tableau[1, MAX] d'entiers (D) nbr, val: entier variables trouvé: booléen i: entier début trouvé faux i 0 tant que non trouvé ET i < nbr faire i i+ 1 trouvé (tab[i] = val) ftq retourne (trouvé) fin Algorithmique 6 : Recherche, complexité, tris
fonction rechSeq (tab, nbre, val) retourne(entier) {renvoie le premier indice où se trouve val dans tab, ‑1 sinon} paramètre s (D) tab: tableau [1, MAX] d'entiers (D) nbr, val: entier variables trouvé: booléen i: entier début trouvé faux i 0 tant que non trouvé ET i < nbr faire i i+1 trouvé (tab[i] = val) ftq si trouvé alorsretourne (i) sinonretourne (‑1) fsi fin Algorithmique 6 : Recherche, complexité, tris
Recherche avec critères procédure rechLesMin (tab_d, nbre_d, tab_r, nbre_r, val) {renvoie dans le tableau tab_r les éléments de tab_d val} paramètre s (D) tab_d: tableau [1, MAX] d'entiers, nbr_d, val: entier (R) tab_r: tableau [1, MAX] d'entiers, nbr_r: entier variables id, ir: entiers début ir 0 pour id l à nbre_d faire si (tab_d[id] val) alors irir+ 1 tab_r[ir] tab_d[id] fsi fpour fin Algorithmique 6 : Recherche, complexité, tris
fonction rechMin (tab, nbre) retourne(entier) {renvoie la plus petite valeur contenue dans le tableau tab} paramètre s (D) tab : tableau [1, MAX] d'entiers, nbr : entier variables i, min : entiers début imin tab[l] pour id 2 à nbre faire si (tab[i] < min) alorsmin tab[i] fsi fpour retourne (tab[min]) fin Algorithmique 6 : Recherche, complexité, tris
fonction rechPosMin (tab, nbre) retourne(entier) {retourne le (dernier) indice de la plus petite valeur du tableau tab} paramètre s (D) tab: tableau [1, MAX] d'entiers, nbr: entier variables i, imin, min: entiers début min tab[1] imin 1 pour id 2 à nbre faire si (tab[i] min) alorsmin tab[i] imin i fsi fpour retourne (imin) fin Algorithmique 6 : Recherche, complexité, tris
Recherche séquentielle dans tableau ordonné fonction rechSeq (tab, nbre, val) retourne(entier) {renvoie le premier indice où se trouve val s'il est dans tab, ‑1 sinon} paramètre s (D) tab: tableau [1, MAX] d'entiers (D) nbr, val: entier variables trouvé, dépassé : booléens ; i : entier début trouvé faux; dépassé faux; i 0 tant que non (trouvé OU dépassé) ET i < nbr faire i i+ 1 trouvé (tab[i] = val) dépassé (tab[i] > val) ftq si trouvé alorsretourne (i) sinonretourne(‑1) fin Algorithmique 6 : Recherche, complexité, tris
Recherche dichotomique • Rappel: les valeurs doivent être triées ! Principe: on vise au milieu du tableau si l'élément visé est plus grand que val, il suffit de chercher à gauche ; s'il est plus grand, il suffit de chercher à droite Algorithmique 6 : Recherche, complexité, tris
Recherche dichotomique fonction rechDicho (tab, nbre, val) retourne(entier) {renvoie un indice où se trouve val s'il est dans tab, ‑1 sinon} paramètre s (D) tab : tableau [1, MAX] d'entiers (D) nbr, val : entier variables trouvé : booléen ; id, if, im: entiers début trouvé faux; id 0 ; if nbre + 1 tant que non trouvé ET (if ‑ id) > 1 faire im (id + if)/2 trouvé (tab[im] = val) si (tab[im] > val) alors if im sinon id im fsi ftq si (id = 0) alors retourne (-1) sinon si (tab[id]=val) alorsretourne(id) sinon retourne (-1) fsi fsi fin Algorithmique 6 : Recherche, complexité, tris
Recherche dichotomique: variantel fonction rechDicho (tab, nbre, val) retourne(entier) {renvoie le plus grand indice où se trouve val s'il est dans tab, ‑1 sinon} paramètre s (D) tab: tableau [1, MAX] d'entiers (D) nbr, val: entier variables id, if, im: entiers début id 0; if nbre+1 tantque (if ‑ id) > 1 faire im (id + if)/2 si (tab[im] > val) alors if im sinon id im fsi ftq si (id = 0) alors retourne (‑1) sinon si (tab[id]=val) alorsretourne(id) sinon retourne (-1) fsi fsi fin Algorithmique 6 : Recherche, complexité, tris
Recherche dichotomique : variante2 fonction rechDicho (tab, nbre, val) retourne (entier) {renvoie le plus petit indice où se trouve val s'il est dans tab, ‑1 sinon} paramètre s (D) tab: tableau [1, MAX] d'entiers (D) nbr, val: entier variables id, if, im: entier début id 0 ; if nbre+ 1 tant que (if ‑ id) > 1 faire im (id + if)/2 si (tab[im] val) alors if im sinon id im fsi ftq si (if = nbre + 1) alorsretourne (‑1) sinon si (tab[if]=val) alorsretourne(if) sinonretourne(‑1) fsi fsi fin Algorithmique 6 : Recherche, complexité, tris
Recherche dans un ABR fonction rech (unAbr, val) retourne(booléen) {renvoieVRAl si val se trouve dans l'ABR unAbr, FAUXsinon} paramètre s (D) unAbr: ABR (D) val: entier variables trouvé: booléen ; id, if, im: entiers début si unAbr.Vide() alorsretourner (FAUX) sinonsi (unAbr.Info() = val) alorsretourner(VRAI) sinonsi (unAbr.Info() < val) alors retourner (Rech(unAbr.FD(), val)) sinon retourner (Rech(unAbr.FG(), val)) fsi fsi fsi fin Algorithmique 6 : Recherche, complexité, tris
Simulation de recherche 20 24 18 27 9 19 32 5 13 2 36 15 8 12 17 7 Algorithmique 6 : Recherche, complexité, tris
Adressage Dispersé Algorithmique 6 : Recherche, complexité, tris
Adressage dispersé • Objectif:classer M éléments dans un tableau • Principe: dans un tableau de p cases, on classe l'élément x, à l’indice k, donné par une fonction d'adressage h • classer un élément x entier k, compris entre 1 et p • Fonction h: h(x)=k • la valeur k ne dépend que de l'élément x ; • l'élément x n'est pas placé relativement aux autres éléments
Quelques exemples de fonctions d’adressage • x : chaîne h1(x) = nombre de caractères de la chaîne h1("Paul") = 4 h1("MmeDupont")=9 • x : entier h2(x) = somme de ses chiffres décimaux h2(342) = 9 h2(100 340) = 8 • x : entier h3(x)= nombre de bits à 1 dans l'écriture binaire h3(342) = h3(101010010) = 4 • x : chaîne de caractères h4(x) = somme des codes ASCII des caractères de la chaîne
Exemple de classement par la fonction d’adressage h1 • Suite de prénoms : • Marc, Izabelle, Paule, Jeanne, Ali, Jo, Michèle • Codes associés par h1 (nb caractères) : 4, 8, 5, 6, 3, 2, 7 • Constatations : • la valeur k ne dépend que de l'élément x ; • la place de l'élément x n'est pas déterminée relativement aux autres éléments classés... • ...à la différence d'un tri avec relation d'ordre où la place d'un élément est déterminée par le nombre d'éléments "meilleurs" selon cet ordre.
Une autre fonction d’adressage • h5 associe à c1…ck la somme : • (Somme (rang de ci dans l’alphabet * i) modulo 9) +1 • Suite de prénoms : Marc, Izabelle, Paule, Jeanne, Jo, Michèle • h5 (Marc) = ((13*1+1*2+18*3+3*4) mod 9) + 1 = 81 mod 9 + 1 = 1 • h5 (Jeanne) = ((10*1+5*2+1*3+14*4+14*5+5*6) mod 9) + 1 = 179 mod 9 + 1 = 9 • h5 (Paule) = ((16*1+1*2+21*3+12*4+5*5) mod 9) + 1 = 1 mod 9 + 1 = 2
Recherche d’un élément Algorithme de recherche d'un élément x dans une table construite par adressage dispersé d'une suite d'éléments : • on calcule le code associé à cet élément x par la fonction d’adressage, soit p. • on compare le contenu de la p-ième case de la table avec l’élément x : si identité, la recherche est positive, sinon elle est négative.
Ajout d’un élément Algorithme d'ajout d'un élément X dans une table construite par adressage dispersé d'une suite d'éléments: • on calcule le code associé à cet élément par la fonction d'adressage, soit p. • on affecte l'élément à la p-ième place dans la table, à condition toutefois que cette place ne soit pas déjà occupée risque de collision
Exemples (avec h5 ) • Recherche de "Isabelle" • code associé par h5 : 1 et tabAdrDisp [1] "Isabelle " recherche négative • Ajout de "Ali" • code associé par h5 : 8 ; tabAdrDisp [8] : " " ajout possible • Ajout de "Lola" • code associé par h5 : 2 ; or tabAdrDisp [2] : "Paule" collision
Méthodes de résolution des collisions : méthodes internes • lnternes car on opère dans le tableau alloué • première possibilité : on utilise la place libre dans le tableau • Algorithme d'ajout d'un élément entré en collision : • à partir du rang de la collision, rechercher la première place libre et y placer l'élément entré en collision. • arrivé à la dernière case du tableau, continuer la recherche à la première case du tableau. • Exemples: "Lola" (avec h5 : 2) et "Isabelle" (avec h5 : 1)
Retrait d’un élément • on calcule le code associé à cet élément x par la fonction d'adressage : soit p ; • on compare le contenu de la p-ième case de la table avec l'élément x : • si identité, on le supprime puis on place dans cette case une marque pour indiquer que l'élément supprimé a pu provoquer d'éventuelles collisions • si non identité, on poursuit la recherche séquentiellement en cas d'éventuelles collisions • arrêt si case vide ou parcours jusqu’à (p-1)
Recherche d’un élément • on calcule le code associé à cet élément x par la fonction d'adressage : soit p. • on compare le contenu de la p-ième case de la table avec l'élément x : • si identité, la recherche est positive, • sinon on poursuit la recherche séquentiellement, en cas d’éventuelles collisions (utiliser les marques) • arrêt avec recherche négative si case vide ou parcours jusqu’à (p-1)
Exemples (avec h5 ) retrait de «Marc» (code 1) recherche de «Isabelle» (code 1) retrait de «Ali» (code 8)
Résolution interne des collisions (suite) • Deuxième solution: on partitionne le tableau en deux : • une zone d'adressage primaire • une zone de débordement • Algorithme d'ajout d'un élément entré en collision : rechercher une place libre dans la zone de débordement et y placer l'élément entré en collision
Exemple • Ajout de «Lola» (code associé par h5 : 2) • puis de «Isabelle» (code associé par h5 : 1) Zone de débordement (à la « suite » du tableau)
Recherche … • on calcule le code associé à cet élément x par la fonction d'adressage, soit p • on compare le contenu de la p-ième case de la table avec l'élément x : si identité, la recherche est positive, sinon on mène une recherche séquentielle dans la zone de débordement du tableau
… et retrait • on calcule le code associé à cet élément x par la fonction d'adressage, soit p • on compare le contenu de la p-ième case de la table avec l'élément x : • si identité, on le supprime puis on place dans cette case une marque pour indiquer que l'élément supprimé a pu provoquer d'éventuelles collisions • si non identité, poursuivre la recherche séquentiellement en cas d'éventuelles collisions, dans la zone de débordement du tableau
Exemples Recherche de «Ali» (h5 : 8), puis «Lola» (h5 : 2) Retrait de «Marc» (h5 : 1) Recherche «Isabelle» (h5 : 1)
Méthodes de résolution externe des collisions • "Externes " car on alloue des zones de stockage supplémentaires • Le tableau contient, pour un code donné, deux informations : • une place de rangement d'un élément (principal) ; • une liste de débordement pour les éléments entrés en collision avec l'élément précédent
Ajout d’un élément • Algorithme d'ajout d'un élément entré en collision : • Créer la liste de débordement associée à ce code si celle‑ci n'existe pas encore, • puis ajouter à cette liste le nouvel élément • Exemple (avec h5): ajout de « Lola » (code 2) Lola
Exemples (suite) ajout de « Isabelle » (1) Isabelle Lola ajout de « José » (1) Lola José Isabelle
Recherche d’un élément • on calcule le code associé à cet élément x par la fonction d'adressage, soit p • on compare le contenu de la première information de la p-ième case de la table avec l'élément x • si identité, la recherche est positive ; • sinon, on mène une recherche séquentielle dans la liste associée Lola • recherche de « Michèle » (7), • puis « Isabelle » (1) José Isabelle
Retrait d’un élément • on calcule le code associé à cet élément x par la fonction d'adressage, soit p • on compare le contenu de la première information de la p-ième case de la table avec l'élément x • si identité, on retire l’élément et on le remplace par l'élé-ment placé en tête de la liste associée, quand elle existe ; • sinon on mène une recherche séquentiellement dans la liste associée, avec retrait si la recherche est positive Lola José • retrait de « Michèle » (7), • puis « Lola » (2) et enfin « Marc » (1) Isabelle
Algorithmes de la méthode d'adressage dispersé avec résolution externe type Info2 = agrégat principal : chaîne{première chaîne associée à un code donné} débord : Liste {objet Liste dont l'information est une chaîne} fin fonction code (uneChaîne) retourne (entier) {retourne la valeur donnée par la fonction d’adressage} paramètre (D) uneChaîne : chaîne
Procédure ajout (table, laChaîne) {ajoute l'élément laChaîne dans une table, par adressage dispersé, avec résolution externe des collisions} paramètres (D/R) table: tableau [1, TAILLEMAX] de Info2 (D) laChaîne : chaîne variables ok: booléen ind: entier début ind code(laChaîne) si table[ind].principal = " " alors {c'est la première occurrence de ce code d'adressage} table[ind].principal laChaîne sinon {il y a collision: la place principale est déjà occupée, d’où ajout dans la liste de débordement,en tête} table[ind].débord.premier() table[ind].débord.insèreAvant(laChaîne) fsi fin
Fonction recherche (table, laChaîne) retourne (booléen) {recherche si l'élément laChaîne est présent dans une table, par adressage dispersé, avec résolution externe des collisions} paramètres (D) table: tableau [1, TAILLEMAX] de Info2 (D) laChaîne : chaîne variables trouvé, ok: booléens; ind : entier début ind code(laChaîne) trouvé table[ind].principal = laChaîne si non trouvé {recherche de laChaîne dans la liste de débordement} alorstable[ind].débord.premier() tant quenon trouvé et nontable[ind].débord.horsListe() faire trouvé (table[ind].débord.info() = laChaîne) table[ind].débord.suivant() ftq fsi retourne (trouvé) fin
Fonction retrait (table, laChaîne) retourne booléen {retire, si possible, l’élément laChaîne d’une table construite par adressage dispersé avec résolution externe des collisions} paramètres (D/R) table: tableau [1, TAILLEMAX] de Info2 (D) laChaîne : chaîne variables ok : booléen; ind : entier début ind code(laChaîne) trouvé (table[ind].principal = laChaîne) si trouvé {alors retrait de laChaîne du champ principal de la table} alors retraitPrincipal (table, laChaîne, ind) sinon{recherche, et éventuel retrait, de laChaîne dans la liste de débordement} ok rechercheRetraitDeborde (table, laChaîne, ind) fsi retourne (ok) fin
Procédure retraitPrincipal (table, laChaîne, ind) {retire l’élément laChaîne du champ Principal du code adresse ind; ce champ reçoit la valeur de tête de la liste de débordement si possible} paramètres (D/R) table: tableau [1, TAILLEMAX] de Info2 (D) laChaîne : chaîne; ind : entier variables elt : Info2; ind : entier début si (table[ind].débord.vide()) {il n’y a pas eu de collision sur ce code} alors{ce code n’adresse plus aucune chaîne} table[ind].principal " " sinon {on récupère l’élément en tête de liste de débordement} table[ind].débord.premier() ; elt table[ind].débord.info() {pour mettre sa valeur dans le champ principal} table[ind].principal elt {et puis on retire la cellule de tête de la liste de débordement}table[ind].débord.supprimer() fsi fin
Fonction rechercheRetraitDéborde(table, laChaîne,ind) {recherce et retire, si possible, l’élément laChaîne de la liste de débordement du code adresse ind} paramètres (D/R) table: tableau [1, TAILLEMAX] de Info2 (D) laChaîne : chaîne; ind : entier variable trouvé : booléen début table[ind].débord.premier() trouvé faux {recherche de laChaîne dans la !iste de débordement} tant que non trouvé et non table[ind].débord.horsListe() faire trouvé (table[ind].débord.info() = laChaîne ) si non trouvé alorstable[ind].débord.suivant() ftq {si trouvé, alors retrait dans la liste de débordement de la table} si trouvé alorstable[ind].débord.supprimer() {le curseur est placé sur laChaîne} retourne (trouvé) fin