Récursivité: recherches et tris

Transcription

Récursivité: recherches et tris
4/26/2010
ALGORITHMES RECURSIFS
Méthodes de recherches et de tris
récursives
Ch. PAUL EMSE ALGORITHMIQUE - RECURSIVITE Recherche et Tris
1
Recherches et tris récursifs
Certains traitements récursifs s'appliquent particulièrement
bien à la problématique des recherches et des tris.
Pour appliquer la récursivité il faut que le problème à résoudre
puisse être décomposé en sous-problème de même nature.
L'arrêt de l'appel récursif se fait à la résolution du problème
élémentaire
Il faut donc une modélisation du problème de la recherche ou
du tri qui soit récursive.
Ch. PAUL EMSE ALGORITHMIQUE - RECURSIVITE Recherche et Tris
2
1
4/26/2010
Recherches et tris récursifs
Recherche dichotomique :
La recherche dans un tableau de taille N conduit à découper le problème
en deux sous problèmes de même nature et à rechercher dans un sous
tableau de taille N/2.
Tri quicksort :
Trier une collection d'objets conduit à :
(pré-traitement) identifier un pivot, répartir la collection en deux souscollections les plus petits et les plus grands.
(appel récursif) relancer le tri sur les 2 sous-collections.
(post-traitement) Le résultat sera la concaténation des deux souscollections revenues triées.
Ch. PAUL EMSE ALGORITHMIQUE - RECURSIVITE Recherche et Tris
3
Recherche dichotomique
Attention uniquement si la collection d’objet est déjà triée.
A chaque étape :
●
Tester si le tableau est vide (en ce cas arrêt des appels récursifs
avec échec)
●
Calculer l'indice moyen (indice max + indice min)/2
●
Comparer la valeur présente à l’indice moyen avec l’objet
recherché,
1. si l'objet recherché est à l'indice moyen (arrêt succès)
2. si l’objet est supérieur ou égal à la valeur t[moyen] relancer
la recherche avec le tableau supérieur,
3. sinon relancer la recherche avec le tableau inférieur.
Ch. PAUL EMSE ALGORITHMIQUE - RECURSIVITE Recherche et Tris
4
2
4/26/2010
Recherche dichotomique - principe
objet = 11
: objet<t[moy]
moy = (max + min) / 2
min
max
7
9
11
12
33
max  moy
min
7
9
11
12
33
Ch. PAUL EMSE ALGORITHMIQUE - RECURSIVITE Recherche et Tris
5
Recherche dichotomique – tests d'arrêt
int RDRec(int min, int max, int objet, int t[])
{
int milieu ;
if (min >= max) return -1;
milieu = (max+min)/2;
if (t[milieu] == objet) return milieu;
. . .
}
Tests d'arrêt
Ch. PAUL EMSE ALGORITHMIQUE - RECURSIVITE Recherche et Tris
6
3
4/26/2010
Recherche dichotomique – appel
récursif sur un sous problème
int RDRec(int min, int max, int objet, int t[])
{
int milieu ;
Rappel récursif sur
if (min >= max) return -1;
un sous-problème
milieu = (max+min)/2;
if (t[milieu] == objet) return milieu;
if (objet < t[milieu])
return RDRec(min, milieu -1, objet, t);
if (objet > t[milieu])
return RDRec(milieu +1, max, objet, t);
return –1;
}
Ch. PAUL EMSE ALGORITHMIQUE - RECURSIVITE Recherche et Tris
7
Recherche dichotomique – arrêts et
appels récursif
int RDRec(int min, int max, int objet, int t[])
{
int milieu ;
Rappel récursif sur
if (min >= max) return -1;
un sous-problème
milieu = (max+min)/2;
if (t[milieu] == objet) return milieu;
if (objet < t[milieu])
return RDRec(min, milieu -1, objet, t);
if (objet > t[milieu])
return RDRec(milieu +1, max, objet, t);
return –1;
}
Tests d'arrêt
Ch. PAUL EMSE ALGORITHMIQUE - RECURSIVITE Recherche et Tris
8
4
4/26/2010
Recherche dichotomique – code
int RDRec(int min, int max, int objet, int t[])
{
int milieu ;
if (min >= max) return -1;
milieu = (max+min)/2;
if (t[milieu] == objet) return milieu;
if (objet < t[milieu])
return RDRec(min, milieu -1, objet, t);
if (objet > t[milieu])
return RDRec(milieu +1, max, objet, t);
return –1;
}
Ch. PAUL EMSE ALGORITHMIQUE - RECURSIVITE Recherche et Tris
9
Tri quicksort - principe
A l’étape courante soit :
L : liste vide – elle est retournée (triée par définition)
L : non vide – choix d'un pivot P dans la liste (premier élément)
Découpage de L en deux sous listes :
Li : liste des éléments inférieurs au pivot,
Ls : liste des éléments supérieurs au pivot.
Tri récursif rappelé sur Li et Ls on obtient : Li-triée et Ls-triée
Liste résultat à l’étape courante :
concaténation de Li-triée et Ls-triée avec la valeur du pivot P entre.
Retour à la fonction appelante de L-triée
Ch. PAUL EMSE ALGORITHMIQUE - RECURSIVITE Recherche et Tris
10
5
4/26/2010
Tri quicksort – exemple d'appel
Post traitement
Pré traitement
5 7 3 4 1 2 9
3 4 1 2
1 2
7 9
4
9
2
2
4
1 2
9
1 2 3 4
7 9
1 2 3 4 5 7 9
Ch. PAUL EMSE ALGORITHMIQUE - RECURSIVITE Recherche et Tris
11
Tri quicksort : définition de la liste
Structure du maillon de la liste :
typedef struct maillon
{
char info[NMAX] ;
struct maillon* suiv;
} MAIL ;
int QScmp(MAIL * A, MAIL * B) retourne 0, 1 ou -1
suivant si le champ info du maillon A est égal, supérieur ou inférieur au
champ info du maillon B
Ch. PAUL EMSE ALGORITHMIQUE - RECURSIVITE Recherche et Tris
12
6
4/26/2010
Tri quicksort : fonctions utilisées
MAIL* tete(MAIL* L) retourne la tête d’une liste L, c'est à dire le premier
élément de la liste.
MAIL* reste(MAIL* L) retourne le reste d'une liste L, c'est à dire le
pointeur vers le deuxième élément de la liste.
MAIL* ajouter-tete(MAIL* P, MAIL* L) retourne une liste dont la tête est P
et le reste L (ajout en tête).
MAIL* concatener(MAIL* D, MAIL* F) retourne la liste constituée par tous
les éléments de la liste D suivis de tous les éléments de la liste F.
Ch. PAUL EMSE ALGORITHMIQUE - RECURSIVITE Recherche et Tris
13
Tri quicksort – test d'arrêt
Test d'arrêt
MAIL * QS(MAIL* L)
{ MAIL *P, *R, *T, *Li=NULL, *Ls=NULL,*Resu ;
if (L == NULL) return NULL;
. . .
}
Ch. PAUL EMSE ALGORITHMIQUE - RECURSIVITE Recherche et Tris
14
7
4/26/2010
Tri quicksort – pré traitement
MAIL * QS(MAIL* L)
{ MAIL *P, *R, *T, *Li=NULL, *Ls=NULL,*Resu ;
if (L == NULL) return NULL;
P = tete(L);
for(R= reste(L) ; R!= NULL ; R= reste(R))
{ T= tete(R);
if (QScmp(P,T) < 0) Ls= ajtete(Ls, T);
else Li= ajtete(Li, T);
pré-traitement
}
. . .
}
Ch. PAUL EMSE ALGORITHMIQUE - RECURSIVITE Recherche et Tris
15
Tri quicksort – appel récursif
MAIL * QS(MAIL* L)
{ MAIL *P, *R, *T, *Li=NULL, *Ls=NULL,*Resu ;
if (L == NULL) return NULL;
P = tete(L);
for(R= reste(L) ; R!= NULL ; R= reste(R))
{ T= tete(R);
if (QScmp(P,T) < 0) Ls= ajtete(Ls, T);
Rappel else Li= ajtete(Li, T);
récursif}
Li = QS(Li);
Ls = QS(Ls);
Res = ajtete(P, Ls);
Res = concatener(Li, Res);
return Res ;
}
Ch. PAUL EMSE ALGORITHMIQUE - RECURSIVITE Recherche et Tris
16
8
4/26/2010
Tri quicksort – post traitement
MAIL * QS(MAIL* L)
{ MAIL *P, *R, *T, *Li=NULL, *Ls=NULL,*Resu ;
if (L == NULL) return NULL;
P = tete(L);
for(R= reste(L) ; R!= NULL ; R= reste(R))
{ T= tete(R);
if (QScmp(P,T) < 0) Ls= ajtete(Ls, T);
else Li= ajtete(Li, T);
}
Li = QS(Li);
Ls = QS(Ls);
Res = ajtete(P, Ls);
Res = concatener(Li, Res);
return Res ;
post-traitement
}
Ch. PAUL EMSE ALGORITHMIQUE - RECURSIVITE Recherche et Tris
17
Tri quicksort - anatomie
Test d'arrêt
MAIL * QS(MAIL* L)
{ MAIL *P, *R, *T, *Li=NULL, *Ls=NULL,*Resu ;
if (L == NULL) return NULL;
P = tete(L);
for(R= reste(L) ; R!= NULL ; R= reste(R))
{ T= tete(R);
if (QScmp(P,T) < 0) Ls= ajtete(Ls, T);
Rappel else Li= ajtete(Li, T);
pré-traitement
récursif}
Li = QS(Li);
Ls = QS(Ls);
Res = ajtete(P, Ls);
Res = concatener(Li, Res);
return Res ;
post-traitement
}
Ch. PAUL EMSE ALGORITHMIQUE - RECURSIVITE Recherche et Tris
18
9
4/26/2010
Tri quicksort - code
MAIL * QS(MAIL* L)
{ MAIL *P, *R, *T, *Li=NULL, *Ls=NULL,*Resu ;
if (L == NULL) return NULL;
P = tete(L);
for(R= reste(L) ; R!= NULL ; R= reste(R))
{ T= tete(R);
if (QScmp(P,T) < 0) Ls= ajtete(Ls, T);
else Li= ajtete(Li, T);
}
Li = QS(Li);
Ls = QS(Ls);
Res = ajtete(P, Ls);
Res = concatener(Li, Res);
return Res ;
}
Ch. PAUL EMSE ALGORITHMIQUE - RECURSIVITE Recherche et Tris
19
10