Structures séquentielles II - Représentation des listes

publicité
Structures séquentielles
II - Représentation des listes
Nathalie Junior Bouquet
Février 2013
1
1.1
Listes itératives : Représentation contiguë (statique)
Le type
La liste est stockée dans un tableau (un vecteur) : la ième case contient le ième élément de la liste.
Cette représentation limite donc la longueur de la liste qui ne peut dépasser la taille du tableau. Afin
de ne prendre en compte que les cases du vecteurs contenant les éléments de la liste, il est nécessaire de
connaître sa longueur. Donc la liste sera représentée par un couple < T ableau, Entier > :
constantes
LMax = 100
types
/* déclaration du type t_element*/
t_vectLMaxElts = LMax t_element
t_liste = enregistrement
t_vectLMaxElts
elts
entier
longueur
fin enregistrement t_liste
variables
t_liste
L.elts
L.longueur
1.2
1.2.1
L
1
2
...
n
e1
n
e2
...
en
...
LMax
Implémentation des opérations
De simples correspondances
Type abstrait : Liste itérative
Implémentation : type t_liste
λ : Liste
L : t_liste
λ ← liste-vide
L.longueur ← 0
longueur (λ)
L.longueur
ième(λ, k)
L.elts[k]
On remarque que la notion de place n’est pas présente ici. Celle-ci n’a pas d’équivalent directe dans
cette implémentation 1 en langage Algo et n’est pas nécessaire à sa manipulation.
1. En C, par exemple, l’accès à la ième place de L peut être représenté par l’adresse mémoire de la ”case“. Ainsi, l’opération
succ est représentée par la succession des cases du tableau en mémoire (il suffit d’incrémenter le pointeur).
1
Algorithmique
Structures séquentielles Les listes – février 2013
1.2.2
Info-Sup
Épita
Des algorithmes
L’accès au k ème élément d’une liste est immédiat. Par contre, pour l’insertion et la suppression, il faut
déplacer tous les éléments de la place où s’effectue l’opération jusqu’à la fin de la liste pour reconstituer
la structure.
Les opérations présentées ici supposent de connaître le rang (donc la place dans le vecteur) de l’élément
à supprimer ou insérer. Les versions vues en td commenceront par effectuer une recherche de cette place.
L’opération supprimer
opérations
supprimer : Liste × Entier → Liste
préconditions
supprimer (λ, k) est-défini-ssi 1 ≤ k ≤ longueur(λ)
axiomes
λ ̸= liste-vide & 1 ≤ k ≤ longueur(λ) ⇒ longueur(supprimer(λ, k)) = longueur(λ) − 1
λ ̸= liste-vide & 1 ≤ k ≤ longueur(λ) & 1 ≤ i < k
⇒ ième(supprimer(λ, k), i) = ième(λ, i)
λ ̸= liste-vide & 1 ≤ k ≤ longueur(λ) & k ≤ i ≤ longueur(λ) − 1
⇒ ième(supprimer(λ, k), i) = ième(λ, i + 1)
avec
λ : Liste
k, i : Entier
L’algorithme que nous écrivons modifie directement la liste passée en paramètre. L’implémentation
proposée ici est une fonction retournant un booléen indiquant si la suppression a réellement été effectuée.
algorithme fonction supprimer : booleen
parametres globaux
t_liste
L
parametres locaux
entier
k
variables
entier
i
debut
si (k<1) ou (k > L.longueur) alors
/* le test L.longueur=0 est inutile ! */
retourne faux
sinon
pour i ← k jusqu’a L.longueur-1 faire
L.elts[i] ← L.elts[i+1]
fin pour
L.longueur ← L.longueur - 1
retourne vrai
fin si
fin algorithme fonction supprimer
Un peu de complexité : Si n est la longueur de la liste, une suppression demande au plus n − 1
affectations (suppression du premier élément = le pire des cas).
L’opération insérer
opérations
insérer : Liste × Entier × Élément → Liste
préconditions
insérer(λ, k, e) est-défini-ssi 1 ≤ k ≤ longueur(λ) + 1
2
Algorithmique
Structures séquentielles Les listes – février 2013
axiomes
1≤k
1≤k
1≤k
1≤k
≤ longueur(λ) + 1
≤ longueur(λ) + 1
≤ longueur(λ) + 1
≤ longueur(λ) + 1
Info-Sup
Épita
⇒ longueur(insérer(λ, k, e)) = longueur(λ) + 1
& 1 ≤ i < k ⇒ ième(insérer(λ, k, e), i) = ième(λ, i)
& k = i ⇒ ième(insérer(λ, k, e), i) = e
& k < i ≤ longueur(λ) + 1
⇒ ième(insérer(λ, k, e), i) = ième(λ, i − 1)
avec
λ : Liste
k, i : Entier
e : Élément
algorithme fonction inserer : booleen
parametres globaux
t_liste
L
parametres locaux
entier
k
t_element e
variables
entier
i
debut
si (L.longueur >= LMax) ou (k < 1) ou (k > L.longueur+1) alors
retourne faux
sinon
pour i ← L.longueur jusqu’a k decroissant faire
L.elts[i+1] ← L.elts[i]
fin pour
L.elts[k] ← e
L.longueur ← L.longueur + 1
retourne vrai
fin si
fin algorithme fonction inserer
L’utilisation de mémoire statique impose de tester que le résultat ne dépassera pas la taille du vecteur
utilisé pour représenter la liste.
Un peu de complexité : Si n est la longueur de la liste, une insertion demande au plus n+1 affectations
(insertion à la première place = pire des cas)
Remarques La représentation contiguë est bien adaptée aux listes itératives : accès et parcours sont
très efficaces. Mais les suppressions et insertions sont coûteuses (à cause des déplacements). De plus, il
est nécessaire de savoir majorer la taille des listes. Elle est par contre moins adaptée aux listes récursives :
l’accès au premier élément est facile, mais les opérations cons et fin sont difficiles à représenter. Nous
verrons, dans la section suivante, la représentation chaînée qui est bien plus adaptée aux listes récursives.
1.3
Extensions
L’opération concaténer
opérations
concaténer : Liste × Liste → Liste
axiomes
longueur(concaténer(λ, λ′ )) = longueur(λ) + longueur(λ′ )
1 ≤ i ≤ longueur(λ)
⇒ ième(concaténer(λ, λ′ ), i) = ième(λ, i)
longueur(λ) + 1 ≤ i ≤ longueur(λ) + longueur(λ′ )
⇒ ième(concaténer(λ, λ′ ), i) = ième(λ′ , i − longueur(λ))
3
Algorithmique
Structures séquentielles Les listes – février 2013
Info-Sup
Épita
avec
λ, λ′ : Liste
i : Entier
algorithme procedure concatener
parametres locaux
t_liste
L1, L2
parametres globaux
t_liste
Lres
variables
entier
i
debut
si L1.longueur + L2.longueur <= LMax alors
pour i ← 1 jusqu’a L1.longueur faire
Lres.elts[i] ← L1.elts[i]
fin pour
pour i ← L1.longueur+1 jusqu’a L1.longueur + L2.longueur faire
Lres.elts[i] ← L2.elts[i-L1.longueur]
fin pour
Lres.longueur ← L1.longueur + L2.longueur
fin si
fin algorithme procedure concatener
Un peu de complexité : Dans tous les cas, le nombre d’affectations est la somme des longueurs des
deux listes.
L’opération est-présent
opérations
est-présent : Liste × Élément → Booléen
axiomes
est-présent(liste-vide,e) = faux
1 ≤ i ≤ longueur(λ) & e = e′ ⇒ est-présent(insérer(λ, i, e), e′ ) = vrai
1 ≤ i ≤ longueur(λ) & e ̸= e′ ⇒ est-présent(insérer(λ, i, e), e′ ) = est-présent(λ,e′ )
avec
λ : Liste
e, e′ : Élément
i : Entier
algorithme fonction est_present : booleen
parametres locaux
t_element
x
t_liste
L
variables
entier
i
debut
i ← 1
tant que (i <= L.longueur) et (x <> L.elts[i]) faire
i ← i+1
fin tant que
retourne (i <= L.longueur)
fin algorithme fonction est-present
Un peu de complexité : Au pire des cas, cette recherche (dite séquentielle) demande n (la longueur
de la liste) comparaisons. Une étude plus approfondie des algorithmes de recherche sera vue en cours.
4
Téléchargement