Version corrigée - Algo, la page

Download Report

Transcript Version corrigée - Algo, la page

api
Epita
Algorithmique
td no 1 − 2 oct. 2014
Des listes
(Version corrigée)
1
Listes contiguës (statiques)
constantes
LMax = ...
types
/* déclaration du type t_element*/
t_vectLMaxElts = LMax t_element
t_liste = enregistrement
t_vectLMaxElts elts
entier
longueur
n enregistrement t_liste
Exercice 1.1 (Recherches)
1. Écrire un algorithme qui recherche un élément dans une liste. L'algorithme devra donner la position
de l'élément s'il est présent, 0 sinon.
2. Optimiser votre algorithme dans le cas où la liste est triée en ordre croissant.
Solution 1.1
1.
(Recherches)
Spécications :
La fonction
recherche
prend en paramètre un élément
position de la première valeur
x
trouvée, 0 si
x
x
et une liste
n'est pas présent dans
L.
Elle retourne la
L.
algorithme fonction recherche : entier
parametres locaux
t_element
t_liste
variables
debut
entier
x
L
i
i ← 1
tant que (i <= L.longueur) et (x <> L.elts[i]) faire
i ← i+1
n tant que
retourne (i mod (L.longueur+1))
n algorithme fonction recherche
2.
Spécications :
La fonction
recherche_triee prend en paramètre un élément x et une liste L croissante. Elle
x trouvée, 0 si x n'est pas présent dans L.
retourne la position de la première valeur
Principe :
On se place sur le premier élément de la liste.
Tant qu'il reste des éléments, et que l'élément courant n'a pas dépassé
suivant.
1
x, on avance à l'élément
api
Epita
Algorithmique
td no 1 − 2 oct. 2014
On a trouvé l'élément si l'élément sur lequel on s'est arrêté (si on n'a pas parcouru toute la
liste) est
x.
algorithme fonction recherche_triee : entier
parametres locaux
t_element
t_liste
variables
debut
entier
x
L
i
i ← 1
tant que (i <= L.longueur) et (x > L.elts[i]) faire
i ← i+1
n tant que
si (i <= L.longueur) et (x = L.elts[i]) alors
retourne i
sinon
retourne 0
n si
n algorithme fonction recherche_triee
Version récursive :
Recherche dichotomique :
algorithme fonction dichotomie : entier
parametres locaux
plus optimale !
t_element x
t_liste
L
entier
g, d
algorithme fonction dichotomie : entier
parametres locaux
t_element
t_liste
x
L
variables
entier m
variables
debut
debut
si g > d alors
retourne 0
sinon
entier g, d, m
g ← 1
d ← L.longueur
tant que g < = d faire
m ← (g+d) div 2
si L.elts[m] = x alors
retourne m
m ← (g+d) div 2
si L.elts[m] = x alors
retourne m
sinon
si x < L.elts[m] alors
retourne dichotomie (x, L, g, m-1)
sinon
retourne dichotomie (x, L, m+1, d)
n si
n si
n si
n algorithme fonction dichotomie
n si
si x < L.elts[m] alors
d ← m-1
sinon
g ← m+1
n si
n tant que
retourne 0
n algorithme fonction dichotomie
// appel :
res ← dichotomie (L, 1, L.longueur)
2
api
Epita
Algorithmique
td no 1 − 2 oct. 2014
Exercice 1.2 (Suppressions)
Écrire un algorithme qui supprime la première occurrence d'une valeur
x
dans une liste
L
triée en
ordre croissant. L'algorithme devra retourner un booléen indiquant si la suppression a pu être eectuée.
Solution 1.2
(Suppressions)
Spécications :
La fonction
x
dans
L
suppression_triee (t_element x, t_liste L) supprime la première occurrence de
triée en ordre croissant. Elle retourne un booléen indiquant si la suppression a pu être
eectuée.
Principe :
•
Recherche :
On se place sur le premier élément de la liste.
Tant qu'il reste des éléments, et que l'élément courant n'a pas dépassé
x,
on avance à l'élément
suivant.
•
Suppression :
Si on a trouvé x (si on n'a pas parcouru toute la liste et si
x) :
◦ On décale toutes les valeurs qui suivent x d'une place à
◦ La longueur de la liste est décrémentée.
l'élément sur lequel on s'est arrêté est
gauche.
algorithme fonction suppression_triee : booleen
parametres locaux
t_element
x
t_liste
L
parametres globaux
variables
debut
entier
i, j
i ← 1
/* recherche de x */
tant que (i <= L.longueur) et (x > L.elts[i]) faire
i ← i+1
n tant que
si (i > L.longueur) ou (x <> L.elts[i]) alors
retourne faux
sinon
pour j ← i+1 jusqu'a L.longueur faire
/* décalages */
L.elts[j-1] ← L.elts[j]
n pour
L.longueur ← L.longueur - 1
retourne vrai
n si
n algorithme fonction suppression_triee
Exercice 1.3 (Insertions)
Écrire un algorithme qui insère un élément
Solution 1.3
x
à sa place dans une liste
(Insertions)
3
L
triée en ordre croissant.
api
Epita
Algorithmique
td no 1 − 2 oct. 2014
Spécications :
La procédure
insertion (t_element x, t_liste L)
insère
x
à sa place dans
L
triée en ordre
croissant.
Principe :
Si le vecteur contenant la liste est plein, l'insertion ne peut pas avoir lieu.
Sinon, on recherche la place de
x
par un parcours séquentiel de la liste : on se place sur le premier
élément, puis tant qu'il reste des éléments et que l'élément courant n'a pas atteint ou dépassé
x,
on
avance à l'élément suivant. On décale alors d'une place à droite toutes les valeurs de la liste de la
n jusqu'à la position de
x,
que l'on peut enn insérer.
algorithme procedure insertion
parametres locaux
t_element
x
t_liste
L
parametres globaux
variables
entier
i, j
debut
si L.longueur < LMax alors
i ← 1
/* recherche de la place de x */
tant que (i <= L.longueur) et (x > L.elts[i]) faire
i ← i+1
n tant que
/* décalages pour placer x à la place i */
← L.longueur jusqu'a i decroissant faire
L.elts[j+1] ← L.elts[j]
pour j
n pour
L.elts[i] ← x
L.longueur ← L.longueur + 1
n si
n algorithme procedure insertion
Exercice 1.4 (Tri par insertion)
Utiliser la procédure d'insertion pour en écrire une seconde qui permet de trier en ordre croissant une
liste (sans construire une deuxième liste).
Solution 1.4
(Tri par insertion)
Spécications :
La procedure
tri_insert (t_liste L)
trie en ordre croissant la liste
algorithme procedure tri_insert
parametres globaux
t_liste
variables
debut
entier
L
i, long
long ← L.longueur
L.longueur ← 0
pour i ← 1 jusqu'a long faire
insertion (L.elts[i], L)
n pour
n algorithme procedure tri_insert
4
L.
api
Epita
Algorithmique
td no 1 − 2 oct. 2014
Exercice 1.5 (Tri à bulles)
Écrire un algorithme qui trie une liste en utilisant la méthode dite "à bulles".
Solution 1.5
(Tri à bulles)
Spécications :
La procedure
tri_bulles (t_liste L)
trie en ordre croissant la liste
L.
algorithme procedure triBulles
parametres globaux
t_liste
variables
debut
entier
booleen
L
i,j
trie
i ← 1
tant que (i < L.longueur) et non trie faire
trie ← vrai
pour j ← 1 jusqu'a l.longueur-i faire
si L.elts[j] > L.elts[j+1] alors
swap (L.elts[j], L.elts[j+1])
trie ← faux
n si
n pour
i ← i+1
n tant que
n algorithme procedure triBulles
2
Listes chaînées (dynamiques)
types
/* déclaration du type t_element*/
t_pListe = ↑t_noeud
t_noeud = enregistrement
t_element val
t_pListe
suiv
n enregistrement t_noeud
Exercice 2.1 (Implémentation du type abstrait
Liste
)
a. Écrire une fonction qui donne la longueur d'une liste chaînée (de type
t_pListe).
ième
b. Écrire une fonction qui retourne un pointeur sur le i
élément d'une liste chaînée, la valeur
s'il n'existe pas.
c. Écrire un algorithme qui concatène deux listes chaînées.
Tous les algorithmes devront d'abord être écrit en
5
itératif,
puis en
récursif
!
nul
api
Epita
Algorithmique
td no 1 − 2 oct. 2014
Solution 2.1
(Implémentation du type abstrait
L'ajout en tête (opération
cons)
Liste
)
:
Version fonction :
Spécications :
La fonction
ajout_tete (t_element x, t_pListe)
ajoute l'élément
x
en tête de la liste
retourne la nouvelle tête de liste.
algorithme fonction ajout_tete : t_pListe
parametres locaux
t_element
t_pListe
x
L
variables
debut
t_pListe
new
allouer (new)
new↑.val ← x
new↑.suiv ← L
retourne new
n algorithme fonction ajout_tete
Utilisation :
tete ← ajout_tete (x, tete)
a. La longueur d'une liste (opération
Spécications :
La fonction
longueur)
longueur(L)
:
retourne la longueur de la liste
algorithme fonction longueur : Entier
parametres locaux
t_pListe
variables
debut
t_pListe
entier
L
p
n
n ← 0
p ← L
tant que p <> nul faire
n ← n + 1
p ← p↑.suiv
n tant que
retourne n
n algorithme fonction longueur
6
L.
L.
Elle
api
Epita
Algorithmique
td no 1 − 2 oct. 2014
b. Le
iième
élément (opération
Spécications :
la liste
L,
accès )
La fonction
la valeur
:
acces (L, k)
nul s'il n'existe pas.
retourne le pointeur (la place) du
k ième
élément de
algorithme fonction acces : t_pListe
parametres locaux
t_pListe
entier
variables
t_pListe
L
k
p
debut
p ← L
tant que (p <> nul) et (k <> 1) faire
k ← k - 1
p ← p↑.suiv
n tant que
retourne p
n algorithme fonction acces
c. La concaténation de deux listes (opération
Spécications :
La procédure
concaténer )
concatener(L1, L2)
:
ajoute la liste L2 à la n de la liste L1.
algorithme procedure concatener
parametres globaux
t_pListe
L1
t_pListe
L2
parametres locaux
variables
t_pListe
p
debut
si L1 = nul alors
L1 ← L2
sinon
si L2 <> nul alors
p ← L1
tant que p↑.suiv <> nul faire
p ← p↑.suiv
n tant que
p↑.suiv ← L2
n si
n si
n algorithme procedure concatener
Exercice 2.2 (Liste chaînée
↔
liste contiguë)
1. Écrire un algorithme qui à partir d'une liste chaînée (du type
(du type
t_liste)
t_pListe)
2. Écrire un algorithme qui, à partir d'une liste contiguë (du type
(du type
construit la liste contiguë
contenant les mêmes éléments, dans le même ordre.
t_pListe)
t_liste),
contenant les mêmes éléments, dans le même ordre.
7
construit la liste chaînée
api
Epita
Algorithmique
td no 1 − 2 oct. 2014
Solution 2.2
1.
(Liste chaînée
Spécications :
La procédure
contiguë
Lstat
↔
liste contiguë)
chainee_to_contigue (t_pListe Ldyn, t_liste Lstat)
à partir de la liste chaînée Ldyn.
construit la liste
Principe :
Il sut de parcourir la liste chaînée. Pour chaque élément, on incrémente la longueur de la
liste statique (initialement à 0), et on place la valeur courante de la liste chaînée à la position
longueur dans le vecteur.
algorithme procedure chainee_to_contigue
parametres locaux
t_pListe
Ldyn
t_liste
Lcont
parametres globaux
debut
Lcont.longueur ← 0
tant que Ldyn <> nul faire
Lcont.longueur ← Lcont.longueur + 1
Lcont.elt[Lcont.longueur] ← Ldyn↑.val
Ldyn ← Ldyn↑.suiv
n tant que
n algorithme procedure chainee_to_contigue
2.
Spécications :
La fonction
contigue_to_chainee (t_liste L) retourne la tête de la liste chaînée construite
L.
à partir de la liste contiguë
Principe :
La nouvelle liste est vide au départ. Chaque élément de la liste contiguë
de la nouvelle liste. La liste
L
L
est inséré en tête
est parcourue à l'envers (de la n au début) an d'obtenir une
liste chaînée dans le bon ordre !
algorithme fonction contigue_to_chainee : t_pListe
parametres locaux
t_liste
L
variables
t_pListe
tete
entier
i
debut tete ← nul pour i ←
L.longueur decroissant jusqu'a 1 faire
ajout_tete (L.elts[i], tete)
n pour
retourne tete
n algorithme fonction contigue_to_chainee
Exercice 2.3 (Listes chaînées triées)
a. Écrire une fonction qui recherche un élément dans une liste chaînée triée. La fonction devra retourner
le pointeur sur l'élément s'il a été trouvé, la valeur
nul sinon.
b. Écrire un algorithme qui insère un élément à sa place dans une liste chaînée triée.
c. Écrire un algorithme qui supprime la première occurrence d'un élément donné dans une liste triée.
8
api
Epita
Algorithmique
td no 1 − 2 oct. 2014
Tous les algorithmes devront d'abord être écrit en
Solution 2.3
a.
itératif,
puis en
récursif
!
(Listes chaînées triées)
Spécications :
La fonction
L.
recherche (t_element x, t_pListe L) recherche l'élément x dans la liste triée
Elle retourne l'adresse de l'élément s'il a été trouvé, la valeur
nul sinon.
Principe :
On parcourt la liste (donc tant qu'il reste des éléments !) tant que l'on n'a pas atteint ou
dépassé la valeur cherchée.
algorithme fonction recherche : t_pListe
parametres locaux
t_element x
t_pListe L
debut
tant que (L <> nul) et (x > l↑.val) faire
L ← L↑.suiv
n tant que
si (L <> nul) et (x = L↑.val) alors
retourne L
sinon
retourne nul
n si
n algorithme fonction recherche
9
api
Epita
Algorithmique
td no 1 − 2 oct. 2014
b.
Spécications :
La procédure
triée
ajout (t_element x, t_pListe L)
ajoute l'élément
x
à sa place dans la liste
L.
Principe :
•
On parcourt la liste tant que l'on n'a pas atteint ou dépassé la valeur cherchée, tout en
conservant un pointeur sur l'élément précédent.
•
L'élément courant est le suivant de notre nouvel élément (il peut ne pas exister : ajout en
n !).
•
Si on ne s'est pas déplacé dans la liste (elle est vide, ou
x
< premier élément), alors on
ajoute en tête, sinon le nouvel élément devient le suivant du précédent.
L
prec
p
1
4
8
12
nul
6
new
algorithme procedure ajout
parametres locaux
t_element
x
t_pListe
L
parametres globaux
variables
t_pListe
p, prec, new
debut
/* recherche de la place avec conservation du précédent */
p ← L
tant que (p <> nul) et (x > p↑.val) faire
prec ← p
p ← p↑.suiv
n tant que
/* ajout */
allouer (new)
new↑.val ← x
new↑.suiv ← p
si p = L alors
L ← new
/* insertion en tête */
sinon
prec↑.suiv ← new
n si
n algorithme procedure ajout
10
api
Epita
Algorithmique
td no 1 − 2 oct. 2014
c.
Spécications :
La fonction
valeur
x
supprime (t_element x, t_pListe L) supprime la première occurrence de la
L. Elle retourne un booléen indiquant si la suppression a eu lieu.
dans la liste triée
Principe :
•
On eectue la boucle de recherche de la valeur, tout en conservant un pointeur sur l'élément
précédent.
•
Si on a trouvé
◦
◦
x
:
soit on est en tête de liste : la nouvelle tête est l'élément suivant,
soit on est au milieu (ou à la n) : le suivant du précédent est le suivant de l'élément à
supprimer !
L
prec
p
1
4
8
12
nul
algorithme fonction supprime : booleen
parametres locaux
t_element
x
t_pListe
L
parametres globaux
variables
t_pListe
debut
p, prec
/* recherche avec conservation du précédent */
p ← L
tant que (p <> nul) et (x > p↑.val) faire
prec ← p
p ← p↑.suiv
n tant que
/* suppression si trouvé */
si (p <> nul) et (x = p↑.val) alors
si p = L alors
/* suppression de la tête */
L ← L↑.suiv
sinon
prec↑.suiv ← p↑.suiv
n si
liberer (p)
retourne vrai
sinon
retourne faux
n si
n algorithme fonction supprime
11
api
Epita
Algorithmique
td no 1 − 2 oct. 2014
Exercice 2.4 (Croissance)
Écrire la fonction qui détermine si une liste chaînée (du type
Solution 2.4
t_pListe)
est strictement croissante.
(Listes chaînées - Croissance)
Spécications :
La fonction
est_croissante (L)
détermine si la liste L, de type
t_pListe,
est strictement crois-
sante.
algorithme fonction est_croissante : booleen
parametres locaux
t_pListe
L
debut
si L = nul alors
retourne vrai
sinon
tant que (L↑.suiv <> nul) et (L↑.val < L↑.suiv↑.val) faire
L ← L↑.suiv
n tant que
retourne (L↑.suiv = nul)
n si
n algorithme fonction est_croissante
Exercice 2.5 (Inversion de liste)
a. Écrire une procédure itérative qui inverse une liste chaînée donnée.
b. Écrire une fonction ou procédure (ce qui vous semble le plus simple) récursive qui inverse une liste
chaînée.
Solution 2.5
a.
(Inversion de liste)
Spécications :
La procédure
inverse_liste (L)
inverse la liste
L,
de type
t_pListe.
algorithme procedure inverse_liste
parametres globaux
t_pListe
L
variables
debut
t_pListe Res, temp
Res ←
nul
tant que L <> nul faire
temp ← L
L ← L↑.suiv
temp↑.suiv ← Res
Res ← temp
n tant que
L ← Res
n algorithme procedure inverse_liste
12