TD04

publicité
Université de Nice-Sophia Antipolis
POLYTECH Peip2
Jeudi 16 mars 2017
Durée: 2h
Algorithmique et Programmation
Travaux Pratiques – Séance no 4
Recherches linéaire et dichotomique
Dans ce TD, vous allez programmer des algorithmes de recherche. Le premier est
une simple recherche linéaire. Le second, plus efficace, suit la méthode dichotomique.
Dans ce qui suit vous utiliserez des listes d’éléments. Un élément, représenté par la
classe Élément, sera formé d’une clé et d’une valeur. Les algorithmes consisteront à
rechercher un élément dans la liste à partir de sa clé. Si la clé est présente dans la
liste, l’algorithme retourne l’élément trouvé. Si la clé n’est pas présente, la recherche
échouera et une exception CléNonTrouvée sera émise.
1) Définissez une classe générique Élément<C,V>, munie des deux attributs valeur et
clé, de constructeurs et de méthodes pour les manipuler.
2) Écrivez, compilez et exécutez le programme suivant :
p u b l i c c l a s s Test {
p u b l i c s t a t i c v o i d main ( String [] args ) {
List < Integer > l1 = new ArrayList < Integer >();
List < String > l2 = new LinkedList < String >();
Élément < Integer , String > e =
new Élément < Integer , String >(3 , " toto " );
//e est un élément de clé 3 et valeur "toto"
System . out . println ( e );
}
}
3) Complétez ce programme afin d’ajouter des valeurs aux listes l1 et l2, puis affichez
les deux listes.
4) Déclarez une liste l3 dont les valeurs sont de type Élément<Integer,String>, ajoutez
des valeurs et affichez la liste l3. Le premier type de Élément désigne le type de sa clé
et le second le type de sa valeur.
1
Recherche linéaire
La recherche linéaire consiste à rechercher séquentiellement, c’est-à-dire, en parcourant les éléments de la liste un à un en partant du premier. L’algorithme est donné
1
ci-dessous.
a l g o r i t h m e rechercher (l , c )
{ R^
o le : rechercher dans la liste l l ’ élément de clé c }
{ Conséquent : retourne l ’ élément e de clé c
∀k , 1 6 k 6 longueur ( l ) , clé ( ième (l , k )) 6= c }
i ← 1
r é p é t e r
x ← ième (l , i )
s i clé ( x )= c a l o r s
rendre x
s i n o n i ← i +1
finsi
{ i 6 longueur ( l )+1 et ∀k , 1 6 k <i , clé ( ième (l , k )) 6= c }
j u s q u ’à i = longueur ( l )
{∀k , 1 6 k 6 longueur ( l ) , clé ( ième (l , k )) 6= c }
e x c e p t i o n CléNonTrouvée
5) Dans une classe Test, programmez cet algorithme en Java dans une méthode statique. Dans la méthode main, construisez une liste d’éléments avec un ArrayList et
testez votre méthode de recherche.
6) Quelle est la complexité de cet algorithme ?
7) Écrivez une seconde version de la méthode de recherche linéaire qui tient compte du
fait que les éléments dans la liste sont ordonnés de façon croissante sur les clés.
8) Construisez une liste ordonnée d’éléments et testez votre seconde méthode de recherche.
9) Quelle est la complexité de ce second algorithme ? Est-il plus efficace ?
2
Recherche dichotomique
La recherche dichotomique est une méthode très efficace. Le principe de l’algorithme est de diviser l’espace de recherche de l’élément en deux espaces de même taille.
L’élément recherché est dans l’un des deux espaces. La recherche se poursuit dans l’espace qui contient l’élément recherché selon la même méthode.
Cette méthode impose que les éléments soient ordonnés, et que l’accès aux éléments
soit direct (sinon la méthode perd toute son efficacité).
Une première version de l’algorithme de recherche dichotomique est donnée cidessous :
a l g o r i t h m e rechercher (l , c )
{ R^
o le : rechercher dans la liste l ordonnée l ’ élément de clé c }
{ Conséquent : si la clé est présente dans la liste , retourne }
{
l ’ élément x tel que clé ( x ) = c }
v a r i a b l e s gauche , droite , milieu t y p e [0 , longueur ( l )+1]
trouvé t y p e booléen
x t y p e Élément
2
gauche ← 1
droite ← longueur ( l )
trouvé ← f a u x
{l ’ espace de recherche est au départ toute la liste }
r é p é t e r
{ gauche6droite et }
{∀ k , 16k<gauche , clé ( ième (l , k ))<c et }
{∀ k , droite<k6longueur ( l ) , clé ( ième (l , k ))>c }
milieu ← ( gauche + droite ) d i v 2
x ← ième (l , milieu )
s i c = clé ( x ) a l o r s trouvé ← v r a i
sinon
s i c < clé ( x ) a l o r s droite ← milieu -1
s i n o n {c > clé ( x ) } gauche ← milieu +1
finsi
finsi
j u s q u ’à trouvé ou gauche > droite
{ clé ( ième (l , milieu ))= c ou ∀k , 16k6longueur ( l ) , clé ( ième (l , k ))6= c }
s i trouvé a l o r s r e n d r e x
sinon
e x c e p t i o n CléNonTrouvée
finsi
10) Quelle la complexité de cet algorithme ?
11) Programmez en Java et testez l’algorithme de recherche dichotomique.
12) Cette recherche effectue quatre tests à chaque itération. Modifiez cet algorithme
pour éliminer un test, en supprimant la variable trouvé dans la boucle.
13) On peut encore faire mieux en regroupant le test d’égalité strict avec un test
d’inégalité. Dans ce cas, cet algorithme ne peut s’arrêter dès qu’il a trouvé l’élément
recherché ! Au contraire, il parcourt l’arbre de décision jusqu’à son terme, de la même
façon que s’il recherchait un élément n’appartenant pas à la table. écrivez cette nouvelle
version de la recherche dichotomique. à quel indice se trouve l’élément recherché ? Si
l’élément recherché apparaı̂t plusieurs fois dans la table, quel est celui trouvé par cette
méthode ? Est-elle plus intéressante que les précédentes ?
14) Est-ce que le choix d’une liste chaı̂née (LinkedList) aurait été judicieux pour la
mise en œuvre des algorithmes de recherche précédents ? Expliquez.
3
Téléchargement