• Aucun résultat trouvé

Tabledesmatières PilesetFiles

N/A
N/A
Protected

Academic year: 2022

Partager "Tabledesmatières PilesetFiles"

Copied!
13
0
0

Texte intégral

(1)

Piles et Files Chapitre 2

Version avec preuves.

Table des matières

1 Listes chainées 2

1.1 Listes simplement chainées . . . 2 1.2 Listes doublement chainées . . . 3

2 Pile : Pile LIFO 6

2.1 Implémentation en utilisant des listes : . . . 6 2.2 A l'aide des classes et de listes : . . . 7 2.3 Création d'une pile avec un liste chainée . . . 8

3 File : pile FIFO 10

3.1 Utilisation des listes . . . 10 3.2 A l'aide des classes et de listes : . . . 11 3.3 Utilisation d'une liste doublement chaînée . . . 12

(2)

1 Listes chainées

Une liste chaînée est une structure de donnée permettant, comme les tableaux, de stocker plusieurs valeurs.

1.1 Listes simplement chainées

Une liste simplement chainée est composée de maillon contenant une valeur et pointant vers un autre maillon.

Valeur ; Valeur Valeur Valeur Valeur

Pointeur Pointeur Pointeur Pointeur Pointeur = None

Tête Maillon Maillon Maillon Queue

On peut ainsi implémenter une liste chainée en python : Création du maillon et de la liste :

class Maillon:

def __init__(self, valeur, suivant=None):

self.valeur = valeur self.suivant = suivant class Liste_simple :

def __init__ (self) : self.tete = None

def ajout(self,element ) :

self.tete = Maillon(element, self.tete) def est_vide(self):

return self.tete == None def element_tete(self) :

return self.tete.valeur def retire(self) :

if not self.est_vide() : a = self.tete.valeur

self.tete = self.tete.suivant return a

def __str__(self) : mot = ""

maille = self.tete

while not maille == None :

mot =mot + str( maille.valeur ) + ","

maille = maille.suivant return mot

(3)

1.2 Listes doublement chainées

Une liste doublement chainée est composée de maillon contenant une valeur et deux poin- teurs : un pointant vers le maillon suivante, et autre vers le maillon précédent.

Pointeur suivant Pointeur suivant Pointeur suivant Pointeur suivant = None

Valeur Valeur Valeur Valeur

Pointeur précédent=None Pointeur précédent Pointeur précédent Pointeur précédent

Tête Maillon Maillon Queue

On peut ainsi implémenter une liste doublement chainée en python : Création du maillon et de la liste :

class Maillon:

def __init__(self, valeur, suivant=None,precedent = None):

self.valeur = valeur self.suivant = suivant self.precedent = precedent class Liste_double :

def __init__ (self) : self.tete = None self.queue = None def est_vide(self):

return (self.tete == None and self.queue == None ) def ajout_queue(self,element ) :

if self.est_vide() :

self.tete = self.queue =Maillon(element) else :

self.queue = Maillon(element,None,self.queue) self.queue.precedent.suivant = self.queue

def ajout_tete(self,element ) : if self.est_vide() :

self.tete = self.queue = Maillon(element) else :

self.tete = Maillon(element, self.tete) self.tete.suivant.precedent = self.tete def element_tete(self) :

return self.tete.valeur

(4)

def element_queue(self) : return self.queue.valeur def __str__(self) :

mot = ""

maille = self.tete

while not maille == None :

mot =mot + str( maille.valeur ) + ","

maille = maille.suivant return mot

Exercice 1 : Écrire les méthodes retire_tete et retire_queue qui éliminent les maillons et renvoient la valeur.

Correction class Maillon:

def __init__(self, valeur, suivant=None,precedent = None):

self.valeur = valeur self.suivant = suivant self.precedent = precedent class Liste_double :

def __init__ (self) : self.tete = None self.queue = None def est_vide(self):

return (self.tete == None and self.queue == None ) def ajout_queue(self,element ) :

if self.est_vide() :

self.tete = self.queue =Maillon(element) else :

self.queue = Maillon(element,None,self.queue) self.queue.precedent.suivant = self.queue

def ajout_tete(self,element ) : if self.est_vide() :

self.tete = self.queue = Maillon(element) else :

self.tete = Maillon(element, self.tete) self.tete.suivant.precedent = self.tete def element_tete(self) :

return self.tete.valeur def element_queue(self) :

return self.queue.valeur

(5)

def retire_tete(self) :

if self.est_vide() : # il n'y pas d'elements print("il y plus d'element")

elif self.tete == self.queue : # il y 1 seul element a = self.tete.valeur

self.tete = self.queue = None return a

else : # il y a au moins deux elements a = self.tete.valeur

self.tete = self.tete.suivant self.tete.precedent = None return a

def retire_queue(self) :

if self.est_vide() : # il n'y pas d'elements print("il y plus d'element")

elif self.tete == self.queue : # il y 1 seul element a = self.tete.valeur

self.tete = self.queue = None return a

else : # il y a au moins deux elements a = self.queue.valeur

self.queue = self.queue.precedent self.queue.suivant = None

return a

def __str__(self) : mot = ""

maille = self.tete

while not maille == None :

mot =mot + str( maille.valeur ) + ","

maille = maille.suivant return mot

(6)

2 Pile : Pile LIFO

La notion de pile est une notion fondamentale en informatique. Tout processeur utilise une pile.

Une pile informatique est tout à fait comparable à une pile d'assiettes. Quand on range une assiette dans une pile, on la pose sur le haut de la pile et quand on veut une assiette dans une pile, on prend celle qui est sur le dessus. Dans une pile informatique, c'est le même principe, on a accès qu'au sommet de la pile, les autres éléments étant invisibles.

Pour les piles, il existe deux opérations : la fonction d'empilement et la fonction de dépile- ment.

ˆ Dans la fonction d'empilement (on dit aussi empilage et push en anglais) on ajoute un élément au sommet de la pile.

ˆ Dans la fonction de dépilage (pop en anglais), on retourne l'élément qui est au sommet de la pile et on le supprime de la pile.

À ces deux opérateurs, il faut ajouter une fonction de création de pile. Dans la littérature anglo-saxonne, les piles se nomment stack ainsi que les les que nous verrons un peu plus tard.

Dans une pile, le dernier élément rentré est le premier qui sort ce qui donne en anglais : (Last In, First Out), on parle de façon abrégée de pile LIFO.

2.1 Implémentation en utilisant des listes :

On utilise le type liste pour implémenter notre pile.

La fonction de création de pile devient donc : Initialisation d'une pile vide :

def cree_pile () : return []

On crée ainsi une pile, initialement vide : p = cree_pile()

Exercice 2 :

1. Écrire la fonctionempile qui prend en entrée une pilep, un élémentaet ajoute l'élément à la pile.

2. Écrire la fonctionpile_vide qui renvoie le booléen correspondant au caractère vide de la pile.

3. Écrire la fonctiondepile qui prend en entrée une pile pet retourne l'élément qui est au sommet de la pile tout en le supprimant de la pile.

Correction

def cree_pile():

return []

def empile(p,element):

(7)

p.append(element) def pile_vide(p) :

return len(p)==0 # ou p == []

def depile(p) :

if pile_vide(p) : print("pile vide") else :

return p.pop()

ma_pile = cree_pile() empile(ma_pile , 5) empile ( ma_pile , 3) empile(ma_pile, 9) def somme(p) :

""" retourne la somme des elements de la pile """

s = 0

while not( pile_vide(p)) : s = s + depile(p) return s

print(somme(ma_pile)) Exercice 3 :

En utilisant les quatre fonctions précédentes, écrire une fonction sommequi somme les éléments d'une pile d'entiers.

Correction

Listing 1 La fonctionsomme

def somme_1 p : s = 0

while not (pile_vide p) : s = s + depile p

done ;

s;;

2.2 A l'aide des classes et de listes :

On peut créer la classe pile : class Pile :

def __init__ ( self) : self.contenu = []

Exercice 4 :

1. Écrire la méthodeempile qui prend un élément a et ajoute l'élément à la pile.

(8)

2. Écrire la méthodepile_vide qui renvoie le booléen correspondant au caractère vide de la pile.

3. Écrire la méthode depile qui retourne l'élément qui est au sommet de la pile tout en le supprimant de la pile.

4. Écrire la méthodelire_sommet qui retourne l'élément qui est au sommet de la pile.

Correction

#Exercice 4 class Pile :

def __init__(self) : self.contenu = []

def empile(self,element) :

self.contenu = [element]+ self.contenu def pile_vide(self) :

return len(self.contenu ) == 0 def depile(self) :

if self.pile_vide() :

print("la pile est vide") else :

a = self.contenu[0]

self.contenu = self.contenu[1:]

return a

def lire_sommet(self) : if self.pile_vide() :

print("la pile est vide") else :

return self.contenu[0]

2.3 Création d'une pile avec un liste chainée

L'idée est d'utiliser une suite de maillons, chaque maillon contenant d'une part une donnée et d'autre part un lien sur le maillon suivant de la chaîne.

class Maillon:

def __init__(self, valeur, suivant=None):

self.valeur = valeur self.suivant = suivant On peut ensuite créer la classe Pile : class Pile:

def __init__(self):

self.taille = 0 # nombre d'assiettes dans la pile self.sommet = None

(9)

Exercice 5 :

1. Écrire la méthodeempile qui prend un élément a et ajoute l'élément à la pile.

2. Écrire la méthodepile_vide qui renvoie le booléen correspondant au caractère vide de la pile.

3. Écrire la méthode depile qui retourne l'élément qui est au sommet de la pile tout en le supprimant de la pile.

4. Écrire la méthodelire_sommet qui retourne l'élément qui est au sommet de la pile.

Correction

#Exercice 4 class Pile :

def __init__(self) : self.contenu = []

def empile(self,element) :

self.contenu = [element]+ self.contenu def pile_vide(self) :

return len(self.contenu ) == 0 def depile(self) :

if self.pile_vide() :

print("la pile est vide") else :

a = self.contenu[0]

self.contenu = self.contenu[1:]

return a

def lire_sommet(self) : if self.pile_vide() :

print("la pile est vide") else :

return self.contenu[0]

(10)

3 File : pile FIFO

Dans une le de caisse d'un supermarché, la première personne qui est rentrée dans la le est la première qui doit en sortir. En informatique, nous avons aussi besoin de gérer des les.

Pour les listes, il existe deux opérations de base : la fonction de mise en le d'attente et la sortie de la le d'attente.

ˆ Dans la fonction d'ajout (add en anglais) d'un élément en n d'une liste d'attente.

ˆ Dans la fonction de prise (take en anglais) de l'élément qui est en tête de la le d'attente et que l'on le supprime de la le.

À ces deux opérateurs, il faut ajouter une fonction de création de le. Dans la littérature anglo-saxonne, les les se nomment queue. Dans une le, le premier élément rentré est le pre- mier qui sort ce qui donne en anglais : (Firt In, First Out), on parle de façon abrégée de pile FIFO.

Nous allons donc simuler les les de deux façons, l'une utilisant des tableaux et l'autre des listes.

3.1 Utilisation des listes

On utilise le type liste pour implémenter notre le.

La fonction de création de le devient donc : Initialisation d'une le vide :

def cree_file () : return []

On crée ainsi une le, initialement vide : f = cree_file()

Exercice 6 :

1. Écrire la fonctionajout qui prend en entrée une le f, un élément a et ajoute l'élément à la le.

Correction

Listing 2 La fonction empile

def ajout (p,a) : p.append(a)

2. Écrire la fonctionfile_vide qui renvoie le booléen correspondant au caractère vide de la pile.

Correction

Listing 3 La fonctionpile_vide

def file_vide (p ) : p == [] ;;

(11)

3. Écrire la fonction retire qui prend en entrée une le f et retourne l'élément qui est en tête de la le tout en le supprimant de la le.

Correction

Listing 4 La fonction depile

def retire p = p.pop(0)

3.2 A l'aide des classes et de listes :

On peut créer la classe le : class File :

def __init__ ( self) : self.contenu = []

Exercice 7 :

1. Écrire la méthodeajout qui prend un élément a et ajoute l'élément à la le.

2. Écrire la méthodefile_vide qui renvoie le booléen correspondant au caractère vide de la le.

3. Écrire la méthode retire qui retourne l'élément qui est au sommet de la le tout en le supprimant de la pile.

4. Écrire la méthodelire_debut qui retourne l'élément qui est en tête de la le.

Correction

# exercice 6 def cree_file() :

return []

def ajout(f,element):

f.append(element) def file_vide(f) :

return f== [] # ou len(f) == 0 def retire(f) :

if file_vide(f) :

print("la file est vide") else :

a = f.pop(0) return a

(12)

3.3 Utilisation d'une liste doublement chaînée

L'idée est d'utiliser une suite de maillons, chaque maillon contenant d'une part une donnée et d'autre part un lien sur le maillon suivant de la chaîne et un lien sur le maillon précédent.

class Maillon:

def __init__(self, valeur, precedent=None, suivant=None):

self.valeur = valeur

self.precedent = precedent self.suivant = suivant class File:

def __init__(self):

self.longueur = 0 self.debut = None self.fin = None

def enfiler(self, valeur):

if self.longueur == 0:

self.debut = self.fin = Maillon(valeur) else:

self.fin = Maillon(valeur, self.fin) self.fin.precedent.suivant = self.fin self.longueur += 1

def defiler(self):

if self.longueur > 0:

valeur = self.debut.valeur if self.longueur > 1:

self.debut = self.debut.suivant self.debut.precedent = None else:

self.debut = self.fin = None self.longueur -= 1

return valeur def estVide(self):

return self.longueur == 0 def __str__(self):

ch = "\nEtat de la file:\n"

maillon = self.debut while maillon != None:

ch += str(maillon.valeur) + " "

maillon = maillon.suivant return ch

q = File() q.enfiler(9) q.enfiler(2) q.enfiler(5)

(13)

print(q) q.defiler() q.enfiler(7)

print("La file est-elle vide: ", q.estVide()) print(q)

print("Longueur de la file:", q.longueur)

Références

Documents relatifs

Pour supprimer un des fi chiers d’une pile, ouvrez simplement la pile et faites glisser l’élément à l’extérieur, vers l’endroit où vous voulez le déposer.. Pour supprimer

Emplacement de la pile.- Pour ˆetre sˆ ur que le programme et la pile n’interf`erent pas, le microprocesseur i8086 a ´et´e con¸cu de telle fa¸con que le code et les

Exemple.- ´ Ecrivons un programme QBasic qui demande un entier naturel (de deux octets) et fait appel ` a un sous-programme en langage machine qui passe la valeur en

– à créer la pile comme un objet récursif (une pile est vide ou bien constituée d'un élément qui est son sommet et d'une pile) … voir question a) ci-dessous ;. – à créer

Alors H est

On s’intéresse dans tout ce problème à une suite infinie de lancers d’une pièce équilibrée autour duquel deux joueurs J et J 0 s’affrontent. Le joueur J l’emporte si

Pour prouver la correction d’une fonction récursive, on procède en général par récurrence : on prouve d’abord que la sortie de la fonction est correcte pour les cas

5. Sur la première pile uniquement, en utilisant le vocabulaire introduit, indiquer ce qui arrive aux électrons au niveau de chacune des électrodes en précisant celle