Classe TasMin⚓︎
Un Tas-Min est un arbre binaire vérifiant les propriétés suivantes :
- c'est un arbre binaire parfait tassé à gauche (tous ses niveaux sont complets sauf éventuellement le dernier qui, dans ce cas, est rempli de gauche à droite) ;
- chaque nœud possède une étiquette. Toutes les étiquettes sont comparables entre elles ;
- chaque nœud a une étiquette strictement inférieure à celle de ses éventuels enfants.
Cette dernière propriété assure que la racine d'un Tas-Min est le nœud dont l'étiquette est minimale.
graph TD
R{12} --> N1{13}
R --> N2{53}
N1 --> N3{65}
N1 --> N4{20}
N2 --> N5{61}
N2 -.-> N6( )
L'objectif de cet exercice est la création d'une classe TasMin. On utilisera la modélisation sous forme d'un tableau redimensionnable. Dans cette modélisation, avec Python :
- le données sont stockées dans un tableau dont la première valeur (à l'indice
0) estNone, - l'étiquette de la racine est stockée à l'indice
1, - si l'étiquette d'un nœud est stockée à l'indice
i:- celle de son enfant gauche, s'il existe, est à l'indice
2 * i, - celle de son enfant droit, s'il existe, est à l'indice
2 * i + 1.
- celle de son enfant gauche, s'il existe, est à l'indice
Tableau redimensionnable
Pour cet exercice, on utilisera le type list de Python, et les méthodes primitives suivantes :
- création d'une liste,
- ajout d'un élément à la fin de la liste,
- suppression et récupération du dernier élément,
- accès en lecture et écriture aux éléments avec l'indice donné.
On n'utilisera pas les tranches, ni aucune fonction native de tri.
On attend une classe TasMin avec les méthodes suivantes :
- Initialisation : on crée un tableau redimensionnable
donneesqui contientNoneen unique élément, on crée un attributeffectifégal à zéro ; est_vide(): détermine si le Tas-Min est vide en renvoyant un booléen ;echange(i, j): échange les valeur d'indicesietjdans le tableaudonnees;ajoute(element):- on augmente
effectifde 1, - on ajoute
elementen fin dedonnees, - on échange les éléments nécessaires pour garder une structure de Tas-Min.
elementremonte la structure arborescente, en échangeant avec son ancêtre, jusqu'à que la structure soit correcte ;
- on augmente
extrait_min():- on enregistre la valeur minimale des données, à l'indice
1, pour la renvoyer en fin de traitement, - on diminue
effectifde 1, - on extrait le dernier élément de
donneespour le placer à l'indice 1, - on échange les éléments nécessaires pour garder une structure de Tas-Min. On commence par échanger l'élément remonté avec le plus petit de ses enfants et l'on poursuit le procédé dans la branche.
- on enregistre la valeur minimale des données, à l'indice
Il n'est pas demandé, ni nécessaire dans cet exercice, d'écrire les tests permettant de vérifier que les paramètres des différentes méthodes sont valides.
On donne un exemple commenté pour chacune des deux dernières méthodes.
Ajouter un élément - exemple
On suppose qu'on dispose d'un Tas-Min, et que l'on souhaite y ajouter l'élément \(17\).
graph TD
R{10} --> N1{42}
R --> N2{23}
N1 --> N3{55}
N1 --> N4{67}
N2 --> N5{31}
N2 --> N6{26}
N3 --> N7{60}
N3 --> N8{59}
N4 --> N9{88}
N4 --> N10{83}
N5 -.-> N11( )
N5 -.-> N12( )
N6 -.-> N13( )
N6 -.-> N14( )
Modélisation : [None, 10, 42, 23, 55, 67, 31, 26, 60, 59, 88, 83]
graph TD
R{10} --> N1{42}
R --> N2{23}
N1 --> N3{55}
N1 --> N4{67}
N2 --> N5{31}
N2 --> N6{26}
N3 --> N7{60}
N3 --> N8{59}
N4 --> N9{88}
N4 --> N10{83}
N5 --> N11{17}
N5 -.-> N12( )
N6 -.-> N13( )
N6 -.-> N14( )
classDef marque fill:#f77,stroke:#333,stroke-width:4px;
class N11 marque;
Modélisation : [None, 10, 42, 23, 55, 67, 31, 26, 60, 59, 88, 83, 17]
L'effectif a augmenté de 1.
graph TD
R{10} --> N1{42}
R --> N2{23}
N1 --> N3{55}
N1 --> N4{67}
N2 --> N5{17}
N2 --> N6{26}
N3 --> N7{60}
N3 --> N8{59}
N4 --> N9{88}
N4 --> N10{83}
N5 --> N11{31}
N5 -.-> N12( )
N6 -.-> N13( )
N6 -.-> N14( )
classDef marque fill:#f77,stroke:#333,stroke-width:4px;
class N5,N11 marque;
Modélisation :
[None, 10, 42, 23, 55, 67, 17, 26, 60, 59, 88, 83, 31]
graph TD
R{10} --> N1{42}
R --> N2{17}
N1 --> N3{55}
N1 --> N4{67}
N2 --> N5{23}
N2 --> N6{26}
N3 --> N7{60}
N3 --> N8{59}
N4 --> N9{88}
N4 --> N10{83}
N5 --> N11{31}
N5 -.-> N12( )
N6 -.-> N13( )
N6 -.-> N14( )
classDef marque fill:#f77,stroke:#333,stroke-width:4px;
class N5,N2 marque;
Modélisation :
[None, 10, 42, 17, 55, 67, 23, 26, 60, 59, 88, 83, 31]
On obtient un Tas-Min.
Extraire le minimum - exemple
On suppose qu'on dispose d'un Tas-Min, et que l'on souhaite extraire le minimum.
graph TD
R{10} --> N1{42}
R --> N2{23}
N1 --> N3{55}
N1 --> N4{67}
N2 --> N5{31}
N2 --> N6{26}
N3 --> N7{60}
N3 --> N8{59}
N4 --> N9{88}
N4 --> N10{83}
N5 -.-> N11( )
N5 -.-> N12( )
N6 -.-> N13( )
N6 -.-> N14( )
Modélisation : [None, 10, 42, 23, 55, 67, 31, 26, 60, 59, 88, 83]
graph TD
R{83} --> N1{42}
R --> N2{23}
N1 --> N3{55}
N1 --> N4{67}
N2 --> N5{31}
N2 --> N6{26}
N3 --> N7{60}
N3 --> N8{59}
N4 --> N9{88}
N4 -.-> N10( )
N5 -.-> N11( )
N5 -.-> N12( )
N6 -.-> N13( )
N6 -.-> N14( )
classDef marque fill:#f77,stroke:#333,stroke-width:4px;
class R,N10 marque;
Modélisation : [None, 83, 42, 23, 55, 67, 31, 26, 60, 59, 88]
L'effectif diminue de 1.
On a pris soin de sauvegarder \(10\) dans une variable.
graph TD
R{23} --> N1{42}
R --> N2{83}
N1 --> N3{55}
N1 --> N4{67}
N2 --> N5{31}
N2 --> N6{26}
N3 --> N7{60}
N3 --> N8{59}
N4 --> N9{88}
N4 -.-> N10( )
N5 -.-> N11( )
N5 -.-> N12( )
N6 -.-> N13( )
N6 -.-> N14( )
classDef marque fill:#f77,stroke:#333,stroke-width:4px;
class R,N2 marque;
Modélisation : [None, 23, 42, 83, 55, 67, 31, 26, 60, 59, 88]
graph TD
R{23} --> N1{42}
R --> N2{26}
N1 --> N3{55}
N1 --> N4{67}
N2 --> N5{31}
N2 --> N6{83}
N3 --> N7{60}
N3 --> N8{59}
N4 --> N9{88}
N4 -.-> N10( )
N5 -.-> N11( )
N5 -.-> N12( )
N6 -.-> N13( )
N6 -.-> N14( )
classDef marque fill:#f77,stroke:#333,stroke-width:4px;
class N6,N2 marque;
Modélisation : [None, 23, 42, 26, 55, 67, 31, 83, 60, 59, 88]
On obtient un Tas-Min. On peut renvoyer la valeur sauvegardée : \(10\).
Difficultés principales
Quand on cherche à extraire le minimum, on passe le dernier en premier, puis on le fait redescendre (de manière répétitive) à la place de son plus petit enfant.
Trois cas peuvent se produire :
- il n'y a pas d'enfants : l'élément est à la bonne position ;
- il y a un enfant à gauche ;
- il y a aussi un enfant à droite ;
Il existe une condition simple entre l'indice d'un nœud et effectif pour savoir si ce nœud a un, deux ou aucun enfant.
On traitera le cas d'effectif 1 à part.
Compléter le code :
# Tests(insensible à la casse)(Ctrl+I)
(Alt+: ; Ctrl pour inverser les colonnes)
(Esc)