TP1 - Prise en main
- Se créer un dossier
Terminale NSIsur votre ordinateur ou clé USB. - Dans ce dossier, créer un dossier
Structures Linéaires. - Créer un nouveau fichier Python nommé
TP1_Prise_En_Main.py.
À la fin de ce TP, vous devrez être capable de :
- représenter une liste chaînée, une pile et une file ;
- comprendre les opérations élémentaires associées à chacune de ces structures ;
- utiliser des primitives pour manipuler une structure de données ;
- distinguer le fonctionnement LIFO d'une pile du fonctionnement FIFO d'une file.
Dans ce TP, nous utiliserons des objets Python simples pour simuler le fonctionnement des structures linéaires.
L'objectif n'est pas d'apprendre de nouvelles méthodes sur les listes Python, mais de comprendre comment fonctionnent les structures de données étudiées.
Listes chaînées
Une liste chaînée est constituée de plusieurs éléments reliés les uns aux autres.
Chaque élément contient :
- une valeur ;
- la suite de la liste.
On adoptera dans ce TP la représentation suivante :
12 → 5 → 32 → ∅
En Python, cette liste sera représentée par :
[12, [5, [32, None]]]
None représente ici la fin de la liste.
Comprendre la représentation
Exercices
- 1
Associer chacune des listes Python suivantes à sa représentation sous forme de chaîne.
L1 = [7, None]
L2 = [4, [8, None]]
L3 = [12, [5, [32, None]]]Par exemple :
? → ? → ∅ - 2
Écrire la représentation Python correspondant à chacune des listes suivantes :
8 → 3 → ∅puis
42 → 17 → 9 → ∅ - 3
Combien d'éléments possède la liste suivante ?
L = [6, [2, [9, [4, None]]]] - 4
Quel est son premier élément ?
- 5
Quelle partie de cette structure correspond à la liste :
2 → 9 → 4 → ∅
Les primitives d'une liste
Pour manipuler notre liste chaînée, on souhaite utiliser uniquement quelques fonctions.
On adoptera les primitives suivantes :
| Primitive | Rôle |
|---|---|
vide() | créer une liste vide |
est_vide(L) | déterminer si une liste est vide |
cons(x, L) | ajouter x au début de L |
tete(L) | obtenir le premier élément |
queue(L) | obtenir la liste privée de son premier élément |
Exercices
- 1
Compléter les fonctions suivantes :
def vide():
return ...
def est_vide(L):
return ...
def cons(x, L):
return ...
def tete(L):
return ...
def queue(L):
return ... - 2
Tester ensuite :
L = vide()
L = cons(32, L)
L = cons(5, L)
L = cons(12, L)
print(L)
Dessiner la liste obtenue sous la forme :
... → ... → ... → ∅
- 3
Que renvoie :
tete(L) - 4
Que renvoie :
queue(L) - 5
Que renvoie :
tete(queue(L))Expliquer ce dernier résultat.
Manipuler une liste chaînée
On considère :
L = vide()
L = cons(8, L)
L = cons(15, L)
L = cons(4, L)
Exercices
- 1
Représenter graphiquement
L. - 2
Sans exécuter le programme, déterminer le résultat de :
tete(L) - 3
Déterminer le résultat de :
queue(L) - 4
Écrire une expression utilisant uniquement
teteetqueuepermettant d'obtenir la valeur8. - 5
Écrire les instructions permettant d'ajouter
20en tête deL. - 6
Écrire une fonction :
def longueur(L):qui renvoie le nombre d'éléments de la liste.
IndicationTant que la liste n'est pas vide, on peut remplacer la liste par sa
queue.
Les piles
Une pile est une structure dans laquelle le dernier élément ajouté est le premier retiré.
On parle de fonctionnement : LIFO : Last In, First Out.
On peut comparer ce fonctionnement à une pile d'assiettes :
┌──────┐
│ 42 │ ← sommet
├──────┤
│ 17 │
├──────┤
│ 8 │
└──────┘
L'élément 42, ajouté en dernier, sera retiré en premier.
Comprendre une pile
Exercices
Une pile est initialement vide.
On effectue successivement les opérations suivantes :
empiler 12
empiler 7
empiler 25
dépiler
empiler 4
- 1
Dessiner l'état de la pile après chaque opération.
- 2
Quelle valeur est retirée lors de l'opération
dépiler? - 3
Quel élément se trouve finalement au sommet de la pile ?
- 4
Dans quel ordre les éléments restants seraient-ils retirés si l'on vidait complètement la pile ?
Programmer une pile
Nous allons représenter une pile à l'aide d'une liste Python.
Le sommet de la pile sera situé à la fin de la liste.
Par exemple :
P = [8, 17, 42]
représente :
┌──────┐
│ 42 │ ← sommet
├──────┤
│ 17 │
├──────┤
│ 8 │
└──────┘
Exercices
- 1
Compléter les primitives suivantes :
def pile_vide():
return ...
def est_vide_pile(P):
return ...
def empiler(x, P):
...
def depiler(P):
...
def sommet(P):
...
def taille_pile(P):
return ...
Une fois ces fonctions écrites, on manipulera les piles uniquement à l'aide de ces primitives.
Par exemple, il sera interdit d'écrire directement :
P.append(12)
dans la suite du TP.
Il faudra écrire :
empiler(12, P)
- 2
Tester les opérations suivantes :
P = pile_vide()
empiler(34, P)
empiler(76, P)
empiler(43, P)
a = depiler(P)
empiler(42, P)
b = taille_pile(P) - 3
Sans utiliser Python, représenter l'état de la pile après chaque instruction.
- 4
Que contient la variable
a? - 5
Que contient la variable
b? - 6
Quel est l'élément situé au sommet de
P?
Retourner une pile
On considère la pile suivante :
┌──────┐
│ 4 │
├──────┤
│ 8 │
├──────┤
│ 12 │
└──────┘
Exercices
On souhaite construire une deuxième pile contenant les mêmes valeurs, mais dans l'ordre inverse :
┌──────┐
│ 12 │
├──────┤
│ 8 │
├──────┤
│ 4 │
└──────┘
- 1
Compléter la fonction suivante :
def inverser_pile(P):
nouvelle = ...
while not ... :
...
return ...Vous devez utiliser uniquement les primitives définies précédemment.
- 2
Créer la pile de l'énoncé, utiliser la fonction sur elle, et vérifier le résultat.
Les files
Une file fonctionne différemment d'une pile.
Le premier élément ajouté est également le premier élément retiré.
On parle de fonctionnement FIFO : First In, First Out.
On peut comparer cette structure à une file d'attente :
sortie ← [Alice] [Bilal] [Chloé] [David] ← entrée
Alice est arrivée en premier : elle quittera donc la file en premier.
Comprendre une file
Exercices
Une file est initialement vide.
On effectue successivement :
enfiler 12
enfiler 7
enfiler 25
défiler
enfiler 4
- 1
Dessiner l'état de la file après chaque opération.
Vous pourrez utiliser la représentation :
sortie ← [ ... ] [ ... ] [ ... ] ← entrée - 2
Quelle valeur est retirée lors de l'opération
défiler? - 3
Quel élément se trouve maintenant en première position ?
- 4
Dans quel ordre les éléments seraient-ils retirés si l'on vidait complètement la file ?
Programmer une file
Une file sera également représentée par une liste Python.
On adoptera la convention suivante :
sortie ← [12, 7, 25] ← entrée
Ainsi :
- les nouveaux éléments sont ajoutés à droite ;
- les éléments sont retirés à gauche.
Exercices
- 1
Compléter les primitives suivantes :
def file_vide():
return ...
def est_vide_file(F):
return ...
def enfiler(x, F):
...
def defiler(F):
...
def premier(F):
...
def taille_file(F):
return ...
Comme pour les piles, la file devra ensuite être manipulée uniquement grâce aux primitives.
- 2
On exécute :
F = file_vide()
enfiler(67, F)
enfiler(34, F)
enfiler(78, F)
a = defiler(F)
enfiler(23, F)
b = taille_file(F)Représenter l'état de la file après chaque opération.
- 3
Que contient
a? - 4
Que contient
b? - 5
Quel élément sera retiré lors du prochain appel à :
defiler(F)
Une file d'impression
En salle des profs, plusieurs enseignants envoient des documents vers une imprimante.
Les documents sont placés dans une file d'impression dans leur ordre d'arrivée.
Exercices
On effectue :
impressions = file_vide()
enfiler("rapport.pdf", impressions)
enfiler("graphique.png", impressions)
enfiler("programme.py", impressions)
- 1
Quel fichier sera imprimé en premier ?
- 2
Quel fichier sera imprimé en dernier ?
- 3
Compléter le programme suivant permettant d'imprimer tous les documents :
while not ... :
document = ...
print("Impression de", ...) - 4
Pourquoi une file est-elle plus adaptée qu'une pile pour gérer les impressions ?
Pile ou file ?
Pour chacune des situations suivantes, indiquer s'il serait plus pertinent d'utiliser une pile ou une file.
Justifier chaque réponse.
Exercices
- 1
Les documents envoyés vers une imprimante.
- 2
La fonction Annuler d'un logiciel de dessin.
- 3
Les clients attendant à une caisse.
- 4
L'historique des pages permettant de revenir à la page précédente dans un navigateur.
- 5
Les tâches envoyées successivement à une machine qui doit les traiter dans leur ordre d'arrivée.
- 6
Les appels successifs de fonctions effectués par un programme.
Le jeu des cartes
On possède une file contenant des cartes numérotées.
Par exemple :
sortie ← [4] [7] [2] [9] [5] ← entrée
On souhaite appliquer plusieurs fois l'opération suivante :
- retirer la première carte ;
- placer cette carte à la fin de la file.
Ainsi :
sortie ← [4] [7] [2] [9] [5] ← entrée
devient :
sortie ← [7] [2] [9] [5] [4] ← entrée
Exercices
- 1
Écrire une fonction :
def rotation(F):qui effectue une rotation de la file.
Vous devez utiliser uniquement les primitives :
enfiler
defiler - 2
Tester votre fonction sur la file définie par :
F = file_vide()
enfiler(4, F)
enfiler(7, F)
enfiler(2, F)
enfiler(9, F)
enfiler(5, F) - 3
Effectuer trois rotations successives et prévoir l'état de la file avant d'exécuter le programme.