M1 MEEF SD maths option info
Représentation d’arbres en Python
1 Plusieurs implémentations
1.1 Le minimum vital
Pour chacune de ces représentations, on pourra coder les fonctions :
noeud(x) crée un nouvel arbre formé d’un seul nœud de valeur x.
racine(a),fg(a) et fd(a) renvoient respectivement la racine, le fils gauche et le fisl droit de a.
modifR(a,x) affecte la nouvelle valeur xà la racine de a.
modifG(a,b) remplace le fils gauche de apar b.
1.2 Chaînage par indices
Dans tout langage proposant des tableaux, on peut construire des arbres sous forme d’un tableau à
3 colonnes :
indice contenu du nœud indice de son fils gauche indice de son fils droit
0 A 1 2
1 B None None
2 C None None
.
.
..
.
..
.
..
.
.
On note que l’indice None représente un fils vide.
Il faut de plus mémoriser :
— l’indice de la racine (on pourrait décider que celle-ci est à l’indice 0 mais pour réorganiser l’arbre
ce n’est pas toujours pratique)
— le nombre de nœuds dans l’arbre (là encore pas indispensable, mais pratique pour savoir quelle
ligne est utilisable pour créer un nouveau nœud)
1.3 Construction « récursive »
Une idée très simple et qui peut suffire ici est de représenter chaque nœud par une liste à 3 éléments
[contenu, fg, fd] ou par une liste vide pour l’arbre vide.
C’est cependant assez limité :
— La taille étant fixée à 3, il serait plus logique d’utiliser un triplet, mais on perdrait le côté mutable
(si on fait du pur fonctionnel ça marche).
— Il devient vite illisible d’écrire a[0] pour le contenu du nœud, a[1] pour son fils gauche, etc.
Une option similaire mais plus agréable est l’utilisation d’un dictionnaire :
>>> a = {’val’:1, ’fg’:None, ’fd’:None}
On accède alors plus confortablement aux composantes du nœud par des « indices » nommés : a[’fg’]
est son fils gauche, etc.
1.4 Un détail un peu pénible
Quelle que soit la représentation choisie, on peut avoir de mauvaises surprises lorsqu’on cherche à
modifier l’arbre par effet de bord. En effet, s’il est possible de modifier n’importe quelle partie de l’arbre,
il est plus difficile de modifier le nœud racine. On rencontre notamment le problème lorsqu’on veut passer
d’un arbre vide à un arbre non vide et réciproquement.
Cela s’explique par le fait que toutes les parties de l’arbre sont embarquées par référence (le modèle
mémoire prédominant en Python), mais que le nœud racine, qui est passé en argument à une fonction,
ne peut lui-même être modifié.
1