From 5e050b384f9fa17186dd755e388f332337d45621 Mon Sep 17 00:00:00 2001 From: Florian Mathieu Date: Tue, 16 Jun 2026 09:38:57 +0200 Subject: [PATCH] =?UTF-8?q?Structures=20lin=C3=A9aires=20:=20nouveau=20cha?= =?UTF-8?q?pitre=20avec=20listes=20cha=C3=AEn=C3=A9es=20+=20d=C3=A9placeme?= =?UTF-8?q?nt=20Pile=5FFile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Progression.md | 3 +- .../Listes_chainees/EXERCICES.md | 101 ++++++++++ .../Listes_chainees/README.md | 172 ++++++++++++++++++ .../Listes_chainees/TP_Playlist.md | 139 ++++++++++++++ .../Pile_File}/Images/File.png | Bin .../Pile_File}/Images/File_td.png | Bin .../Pile_File}/Images/Pile.odg | Bin .../Pile_File}/Images/Pile.png | Bin .../Pile_File}/Images/Pile_td.png | Bin .../Pile_File}/Images/bo_1.png | Bin .../Pile_File}/Images/bo_2.png | Bin .../Pile_File}/README.md | 0 .../Pile_File}/TD/Corrige_TD_Pile_File.md | 0 .../Pile_File}/TD/TD_Pile_File.md | 0 .../Pile_File}/TP/Bataille_correction.py | 0 .../Pile_File}/TP/Corrige_TP_Navigateur.py | 0 .../Pile_File}/TP/File.py | 0 .../Pile_File}/TP/TP_File.md | 0 .../Pile_File}/TP/TP_Navigateur.md | 0 .../Pile_File}/TP/TP_Pile.md | 0 .../Pile_File}/TP/TP_Pile_correction.py | 0 .../Pile_File}/TP/carte_eleve.py | 0 Structures_lineaires/README.md | 30 +++ 23 files changed, 444 insertions(+), 1 deletion(-) create mode 100644 Structures_lineaires/Listes_chainees/EXERCICES.md create mode 100644 Structures_lineaires/Listes_chainees/README.md create mode 100644 Structures_lineaires/Listes_chainees/TP_Playlist.md rename {Pile_File => Structures_lineaires/Pile_File}/Images/File.png (100%) rename {Pile_File => Structures_lineaires/Pile_File}/Images/File_td.png (100%) rename {Pile_File => Structures_lineaires/Pile_File}/Images/Pile.odg (100%) rename {Pile_File => Structures_lineaires/Pile_File}/Images/Pile.png (100%) rename {Pile_File => Structures_lineaires/Pile_File}/Images/Pile_td.png (100%) rename {Pile_File => Structures_lineaires/Pile_File}/Images/bo_1.png (100%) rename {Pile_File => Structures_lineaires/Pile_File}/Images/bo_2.png (100%) rename {Pile_File => Structures_lineaires/Pile_File}/README.md (100%) rename {Pile_File => Structures_lineaires/Pile_File}/TD/Corrige_TD_Pile_File.md (100%) rename {Pile_File => Structures_lineaires/Pile_File}/TD/TD_Pile_File.md (100%) rename {Pile_File => Structures_lineaires/Pile_File}/TP/Bataille_correction.py (100%) rename {Pile_File => Structures_lineaires/Pile_File}/TP/Corrige_TP_Navigateur.py (100%) rename {Pile_File => Structures_lineaires/Pile_File}/TP/File.py (100%) rename {Pile_File => Structures_lineaires/Pile_File}/TP/TP_File.md (100%) rename {Pile_File => Structures_lineaires/Pile_File}/TP/TP_Navigateur.md (100%) rename {Pile_File => Structures_lineaires/Pile_File}/TP/TP_Pile.md (100%) rename {Pile_File => Structures_lineaires/Pile_File}/TP/TP_Pile_correction.py (100%) rename {Pile_File => Structures_lineaires/Pile_File}/TP/carte_eleve.py (100%) create mode 100644 Structures_lineaires/README.md diff --git a/Progression.md b/Progression.md index 10373ef..80dee10 100644 --- a/Progression.md +++ b/Progression.md @@ -5,7 +5,8 @@ | 2 - b | Diviser pour régner : tri fusion, dichotomie récursive | Exercices diviser pour régner | | 3 - a | POO : classes, attributs, méthodes, encapsulation | TP Pokémon | | 3 - b | Paradigmes : fonctionnel, impératif, orienté objet | TP SpotifyWrapped | -| 4 | Structures linéaires : Pile, File — implémentation et usages | TP Pile, TP File, TP Navigateur | +| 4 - a | Structures linéaires : Listes chaînées — maillon, insertion, suppression, récursivité | TP Playlist | +| 4 - b | Structures linéaires : Pile, File — implémentation et usages | TP Pile, TP File, TP Navigateur | | 5 - a | Bases de données : modèle relationnel, conception, clés | TP StreamFlix | | 5 - b | SQL : requêtes, jointures, agrégation | TP Streaming Musical | | 6 | Arbres : arbres binaires, ABR, parcours, applications | TP Livre Dont Vous Êtes le Héros, TP Recommandation | diff --git a/Structures_lineaires/Listes_chainees/EXERCICES.md b/Structures_lineaires/Listes_chainees/EXERCICES.md new file mode 100644 index 0000000..657b2b5 --- /dev/null +++ b/Structures_lineaires/Listes_chainees/EXERCICES.md @@ -0,0 +1,101 @@ +# Exercices — Listes chaînées + +--- + +## Exercice 1 : Comprendre les maillons + +On dispose du code suivant : + +```python +class Maillon: + def __init__(self, valeur, suivant=None): + self.valeur = valeur + self.suivant = suivant + +m3 = Maillon(30) +m2 = Maillon(20, m3) +m1 = Maillon(10, m2) +``` + +1. Représenter schématiquement la liste chaînée obtenue (avec les flèches). +2. Quelle est la valeur de `m1.suivant.valeur` ? +3. Quelle est la valeur de `m1.suivant.suivant.valeur` ? +4. Que vaut `m3.suivant` ? + +--- + +## Exercice 2 : Parcourir une liste + +On dispose d'une liste chaînée `l` dont la tête pointe vers `10 → 20 → 30 → 40 → None`. + +```python +def afficher(liste): + courant = liste.tete + while courant is not None: + print(courant.valeur) + courant = courant.suivant +``` + +1. Dérouler manuellement l'exécution de `afficher(l)` : quelle est la valeur de `courant` à chaque tour de boucle ? +2. Combien de fois la boucle s'exécute-t-elle ? +3. Modifier la fonction pour qu'elle affiche les valeurs séparées par ` → ` sur une seule ligne (comme dans le cours). + +--- + +## Exercice 3 : Opérations de base + +Implémenter les méthodes suivantes dans la classe `ListeChainee` : + +1. `inserer_en_queue(self, valeur)` → ajoute un maillon à la fin de la liste. + *Indication : parcourir jusqu'au dernier maillon, puis modifier son `.suivant`.* + +2. `supprimer_valeur(self, valeur)` → supprime le premier maillon contenant `valeur`. + *Cas particuliers : valeur en tête, valeur absente.* + +3. `nieme(self, n)` → renvoie la valeur du n-ième maillon (indice 0 = tête). + *Lever une `IndexError` si n est hors bornes.* + +--- + +## Exercice 4 : Complexité + +Pour une liste chaînée de longueur n, indiquer la complexité (O(1) ou O(n)) des opérations suivantes et justifier : + +| Opération | Complexité | Justification | +|-----------|------------|---------------| +| Insérer en tête | | | +| Insérer en queue | | | +| Supprimer en tête | | | +| Accéder au n-ième élément | | | +| Rechercher une valeur | | | + +--- + +## Exercice 5 : Version récursive + +1. Écrire la fonction récursive `longueur_rec(maillon)` qui renvoie le nombre de maillons à partir de `maillon`. + +2. Écrire la fonction récursive `rechercher_rec(maillon, valeur)` qui renvoie `True` si `valeur` est présente, `False` sinon. + +3. Écrire la fonction récursive `renverser(maillon)` qui renvoie une nouvelle liste chaînée dont les éléments sont dans l'ordre inverse. + *Exemple : `10 → 20 → 30 → None` devient `30 → 20 → 10 → None`.* + +--- + +## Exercice 6 : Implémenter une Pile avec une liste chaînée + +En utilisant `Maillon`, implémenter la classe `Pile` avec les méthodes : +- `empiler(valeur)` → ajoute au sommet +- `depiler()` → retire et renvoie le sommet +- `sommet()` → consulte le sommet sans le retirer +- `est_vide()` → renvoie `True` si la pile est vide + +Tester avec : empiler 1, 2, 3, puis dépiler jusqu'à vide. + +--- + +Auteur : Florian Mathieu + +Licence CC BY NC + +Licence Creative Commons
Ce cours est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International. diff --git a/Structures_lineaires/Listes_chainees/README.md b/Structures_lineaires/Listes_chainees/README.md new file mode 100644 index 0000000..bf4e9e0 --- /dev/null +++ b/Structures_lineaires/Listes_chainees/README.md @@ -0,0 +1,172 @@ +# Listes chaînées + +> Un tableau Python (`list`) permet d'accéder à n'importe quel élément en O(1) grâce aux indices — mais insérer ou supprimer un élément au milieu déplace tous ceux qui suivent. La liste chaînée adopte une autre approche : chaque élément connaît son successeur, et seuls les liens changent lors d'une modification. + +## 1. Limite des tableaux pour certains usages + +```python +t = [1, 2, 3, 4, 5] +t.insert(2, 99) # insère 99 à l'indice 2 +# → [1, 2, 99, 3, 4, 5] +# Python a dû décaler 3, 4, 5 vers la droite : O(n) +``` + +Pour un tableau de 10 millions d'éléments, une insertion au début déplace 10 millions de valeurs. La liste chaînée résout ce problème : insérer en tête est toujours O(1). + +--- + +## 2. Le maillon + +L'unité de base d'une liste chaînée est un **maillon** (ou cellule, ou nœud). Il contient : +- une **valeur** (la donnée stockée) +- un **pointeur** vers le maillon suivant (ou `None` si c'est le dernier) + +```python +class Maillon: + def __init__(self, valeur, suivant=None): + self.valeur = valeur + self.suivant = suivant +``` + +On peut enchaîner des maillons manuellement : + +```python +m3 = Maillon(30) +m2 = Maillon(20, m3) +m1 = Maillon(10, m2) +# m1 → m2 → m3 → None +# 10 → 20 → 30 → None +``` + +--- + +## 3. La classe ListeChainee + +On encapsule la liste dans une classe qui mémorise uniquement la **tête** (premier maillon) : + +```python +class ListeChainee: + def __init__(self): + self.tete = None # liste vide + + def est_vide(self): + return self.tete is None +``` + +### Insérer en tête + +```python +def inserer_en_tete(self, valeur): + nouveau = Maillon(valeur, self.tete) + self.tete = nouveau +``` + +``` +Avant : tete → [20] → [30] → None +Après : tete → [10] → [20] → [30] → None +``` + +### Supprimer en tête + +```python +def supprimer_en_tete(self): + if self.est_vide(): + raise IndexError("Liste vide") + valeur = self.tete.valeur + self.tete = self.tete.suivant + return valeur +``` + +### Afficher la liste + +```python +def afficher(self): + courant = self.tete + elements = [] + while courant is not None: + elements.append(str(courant.valeur)) + courant = courant.suivant + print(" → ".join(elements) + " → None") +``` + +```python +l = ListeChainee() +l.inserer_en_tete(30) +l.inserer_en_tete(20) +l.inserer_en_tete(10) +l.afficher() +# 10 → 20 → 30 → None +``` + +### Longueur + +```python +def longueur(self): + courant = self.tete + n = 0 + while courant is not None: + n += 1 + courant = courant.suivant + return n +``` + +### Rechercher + +```python +def rechercher(self, valeur): + courant = self.tete + while courant is not None: + if courant.valeur == valeur: + return True + courant = courant.suivant + return False +``` + +--- + +## 4. Structure récursive + +Une liste chaînée est naturellement **récursive** : +- soit elle est **vide** +- soit elle est un **maillon** (tête) suivi d'une **liste chaînée** (queue) + +On peut écrire la longueur de manière récursive : + +```python +def longueur_rec(maillon): + if maillon is None: + return 0 + return 1 + longueur_rec(maillon.suivant) +``` + +Cette vision récursive ("tête + queue") est la même qu'on retrouve dans les arbres (chapitre Arbres). + +--- + +## 5. Liste chaînée vs tableau Python + +| | Tableau Python (`list`) | Liste chaînée | +|---|---|---| +| Accès par indice | O(1) | O(n) | +| Insertion en tête | O(n) | O(1) | +| Suppression en tête | O(n) | O(1) | +| Mémoire | Contiguë | Dispersée (maillons) | +| Usage naturel | Accès aléatoire | Insertion/suppression fréquentes | + +--- + +## 6. Lien avec Pile et File + +Une **pile** (LIFO) s'implémente naturellement avec une liste chaînée : `inserer_en_tete` = empiler, `supprimer_en_tete` = dépiler. + +Une **file** (FIFO) s'implémente avec deux pointeurs : tête pour supprimer, queue pour insérer. + +C'est précisément ce que vous allez implémenter dans le chapitre suivant. + +--- + +Auteur : Florian Mathieu + +Licence CC BY NC + +Licence Creative Commons
Ce cours est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International. diff --git a/Structures_lineaires/Listes_chainees/TP_Playlist.md b/Structures_lineaires/Listes_chainees/TP_Playlist.md new file mode 100644 index 0000000..099ffff --- /dev/null +++ b/Structures_lineaires/Listes_chainees/TP_Playlist.md @@ -0,0 +1,139 @@ +# TP — Playlist musicale + +> Implémenter une playlist sous forme de liste chaînée : ajouter des titres, en retirer, naviguer d'un morceau à l'autre — et comprendre pourquoi cette structure est naturellement adaptée à ce type d'usage. + +--- + +## Contexte + +Un lecteur de musique gère une **playlist** : une séquence de titres qu'on peut modifier en cours de route (ajouter un titre, supprimer un titre, passer au suivant). Un tableau Python serait peu adapté à ces insertions et suppressions fréquentes — la liste chaînée l'est beaucoup mieux. + +--- + +## Partie 1 : La structure de base + +### Étape 1 — Le maillon + +Implémenter la classe `Titre` qui représente un maillon de la playlist : + +```python +class Titre: + def __init__(self, nom, artiste, suivant=None): + self.nom = nom + self.artiste = artiste + self.suivant = suivant + + def __str__(self): + return f"{self.nom} — {self.artiste}" +``` + +### Étape 2 — La playlist + +Implémenter la classe `Playlist` : + +```python +class Playlist: + def __init__(self, nom): + self.nom = nom + self.tete = None + self.courant = None # titre en cours de lecture +``` + +--- + +## Partie 2 : Gestion de la playlist + +### Question 1 + +Implémenter `ajouter_en_tete(self, nom, artiste)` → ajoute un titre au début de la playlist. + +### Question 2 + +Implémenter `ajouter_en_queue(self, nom, artiste)` → ajoute un titre à la fin. + +*Quelle méthode est en O(1) ? Laquelle est en O(n) ? Pourquoi ?* + +### Question 3 + +Implémenter `supprimer(self, nom)` → supprime le premier titre dont le nom correspond. +Gérer le cas où le titre est en tête, en milieu, ou absent. + +### Question 4 + +Implémenter `afficher(self)` → affiche tous les titres de la playlist dans l'ordre, numérotés. + +``` +Playlist : "Ma playlist" +1. Bohemian Rhapsody — Queen +2. Blinding Lights — The Weeknd +3. Starboy — The Weeknd +``` + +--- + +## Partie 3 : Lecture + +### Question 5 + +Implémenter `lecture_suivante(self)` → passe au titre suivant dans la playlist. +- Si `courant` est `None`, commencer par la tête. +- Si `courant` est le dernier titre, retourner au début (liste circulaire). + +### Question 6 + +Implémenter `lire(self)` → affiche le titre en cours de lecture. + +``` +♪ En cours : Bohemian Rhapsody — Queen +``` + +--- + +## Partie 4 : Fonctionnalités avancées + +### Question 7 + +Implémenter `longueur(self)` → renvoie le nombre de titres. + +### Question 8 + +Implémenter `rechercher(self, artiste)` → renvoie la liste de tous les titres d'un artiste donné. + +### Question 9 — Défi + +Implémenter `melanger(self)` → réorganise les titres dans un ordre aléatoire. + +*Indication : convertir la liste chaînée en tableau Python, mélanger avec `random.shuffle`, reconstruire la liste chaînée.* + +--- + +## Partie 5 : Test complet + +```python +p = Playlist("Ma playlist") +p.ajouter_en_queue("Bohemian Rhapsody", "Queen") +p.ajouter_en_queue("Blinding Lights", "The Weeknd") +p.ajouter_en_queue("Starboy", "The Weeknd") +p.ajouter_en_tete("Hotel California", "Eagles") + +p.afficher() +print(f"Longueur : {p.longueur()}") + +p.lecture_suivante() +p.lire() +p.lecture_suivante() +p.lire() + +p.supprimer("Starboy") +p.afficher() + +print(p.rechercher("The Weeknd")) +``` + +--- + +Auteur : Florian Mathieu + +Licence CC BY NC + +Licence Creative Commons
Ce cours est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International. diff --git a/Pile_File/Images/File.png b/Structures_lineaires/Pile_File/Images/File.png similarity index 100% rename from Pile_File/Images/File.png rename to Structures_lineaires/Pile_File/Images/File.png diff --git a/Pile_File/Images/File_td.png b/Structures_lineaires/Pile_File/Images/File_td.png similarity index 100% rename from Pile_File/Images/File_td.png rename to Structures_lineaires/Pile_File/Images/File_td.png diff --git a/Pile_File/Images/Pile.odg b/Structures_lineaires/Pile_File/Images/Pile.odg similarity index 100% rename from Pile_File/Images/Pile.odg rename to Structures_lineaires/Pile_File/Images/Pile.odg diff --git a/Pile_File/Images/Pile.png b/Structures_lineaires/Pile_File/Images/Pile.png similarity index 100% rename from Pile_File/Images/Pile.png rename to Structures_lineaires/Pile_File/Images/Pile.png diff --git a/Pile_File/Images/Pile_td.png b/Structures_lineaires/Pile_File/Images/Pile_td.png similarity index 100% rename from Pile_File/Images/Pile_td.png rename to Structures_lineaires/Pile_File/Images/Pile_td.png diff --git a/Pile_File/Images/bo_1.png b/Structures_lineaires/Pile_File/Images/bo_1.png similarity index 100% rename from Pile_File/Images/bo_1.png rename to Structures_lineaires/Pile_File/Images/bo_1.png diff --git a/Pile_File/Images/bo_2.png b/Structures_lineaires/Pile_File/Images/bo_2.png similarity index 100% rename from Pile_File/Images/bo_2.png rename to Structures_lineaires/Pile_File/Images/bo_2.png diff --git a/Pile_File/README.md b/Structures_lineaires/Pile_File/README.md similarity index 100% rename from Pile_File/README.md rename to Structures_lineaires/Pile_File/README.md diff --git a/Pile_File/TD/Corrige_TD_Pile_File.md b/Structures_lineaires/Pile_File/TD/Corrige_TD_Pile_File.md similarity index 100% rename from Pile_File/TD/Corrige_TD_Pile_File.md rename to Structures_lineaires/Pile_File/TD/Corrige_TD_Pile_File.md diff --git a/Pile_File/TD/TD_Pile_File.md b/Structures_lineaires/Pile_File/TD/TD_Pile_File.md similarity index 100% rename from Pile_File/TD/TD_Pile_File.md rename to Structures_lineaires/Pile_File/TD/TD_Pile_File.md diff --git a/Pile_File/TP/Bataille_correction.py b/Structures_lineaires/Pile_File/TP/Bataille_correction.py similarity index 100% rename from Pile_File/TP/Bataille_correction.py rename to Structures_lineaires/Pile_File/TP/Bataille_correction.py diff --git a/Pile_File/TP/Corrige_TP_Navigateur.py b/Structures_lineaires/Pile_File/TP/Corrige_TP_Navigateur.py similarity index 100% rename from Pile_File/TP/Corrige_TP_Navigateur.py rename to Structures_lineaires/Pile_File/TP/Corrige_TP_Navigateur.py diff --git a/Pile_File/TP/File.py b/Structures_lineaires/Pile_File/TP/File.py similarity index 100% rename from Pile_File/TP/File.py rename to Structures_lineaires/Pile_File/TP/File.py diff --git a/Pile_File/TP/TP_File.md b/Structures_lineaires/Pile_File/TP/TP_File.md similarity index 100% rename from Pile_File/TP/TP_File.md rename to Structures_lineaires/Pile_File/TP/TP_File.md diff --git a/Pile_File/TP/TP_Navigateur.md b/Structures_lineaires/Pile_File/TP/TP_Navigateur.md similarity index 100% rename from Pile_File/TP/TP_Navigateur.md rename to Structures_lineaires/Pile_File/TP/TP_Navigateur.md diff --git a/Pile_File/TP/TP_Pile.md b/Structures_lineaires/Pile_File/TP/TP_Pile.md similarity index 100% rename from Pile_File/TP/TP_Pile.md rename to Structures_lineaires/Pile_File/TP/TP_Pile.md diff --git a/Pile_File/TP/TP_Pile_correction.py b/Structures_lineaires/Pile_File/TP/TP_Pile_correction.py similarity index 100% rename from Pile_File/TP/TP_Pile_correction.py rename to Structures_lineaires/Pile_File/TP/TP_Pile_correction.py diff --git a/Pile_File/TP/carte_eleve.py b/Structures_lineaires/Pile_File/TP/carte_eleve.py similarity index 100% rename from Pile_File/TP/carte_eleve.py rename to Structures_lineaires/Pile_File/TP/carte_eleve.py diff --git a/Structures_lineaires/README.md b/Structures_lineaires/README.md new file mode 100644 index 0000000..c705dd1 --- /dev/null +++ b/Structures_lineaires/README.md @@ -0,0 +1,30 @@ +# Structures de données linéaires + +> Un tableau Python permet d'accéder instantanément à n'importe quel élément par son indice. Mais certains problèmes demandent des structures plus souples : ajouter ou supprimer des éléments sans déplacer tout le reste, ou imposer un ordre d'accès strict. C'est l'objet de ce chapitre. + +## Programme + +![bo.png](assets/bo.png) + +## Les trois structures au programme + +| Structure | Accès | Insertion | Suppression | Usage typique | +|-----------|-------|-----------|-------------|---------------| +| **Liste chaînée** | Séquentiel | En tête : O(1) | En tête : O(1) | Structure de base, implémente pile et file | +| **Pile** (stack) | Dernier entré (LIFO) | En tête : O(1) | En tête : O(1) | Appels de fonctions, annulation (Ctrl+Z) | +| **File** (queue) | Premier entré (FIFO) | En queue : O(1) | En tête : O(1) | File d'attente, BFS, impression | + +## Ressources + +| Fichier | Description | +|---------|-------------| +| [Listes chaînées](Listes_chainees/README.md) | La brique de base : maillon, insertion, suppression, parcours | +| [Piles et Files](Pile_File/README.md) | Deux structures aux contraintes d'accès strictes | + +--- + +Auteur : Florian Mathieu + +Licence CC BY NC + +Licence Creative Commons
Ce cours est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International.