<?xml version="1.0" encoding="UTF-8"?>
<quiz>
<question type="category">
  <category>
    <text>$course$/QCM de NSI/Terminale/Arbres binaires</text>
  </category>
  <info format="html">
    <text><![CDATA[<p>Définition d'un arbre binaire (nœuds, racine, feuilles,<br/>
sous-arbres), terminologie (hauteur, profondeur, taille),<br/>
parcours en profondeur (préfixe, infixe, postfixe) et en<br/>
largeur, propriétés des arbres équilibrés et complets,<br/>
applications.</p>]]></text>
  </info>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q01 : Définition d'un arbre binaire</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'est-ce qu'un <strong>arbre binaire</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Vocabulaire : <strong>racine</strong> (sommet), <strong>nœud interne</strong><br/>
(au moins un enfant), <strong>feuille</strong> (aucun enfant),<br/>
<strong>sous-arbre</strong> (arbre formé par un nœud et ses<br/>
descendants). Cette définition est fondamentale.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un arbre dont chaque nœud contient exactement deux valeurs numériques distinctes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : « binaire » fait référence au nombre<br/>
d'enfants, pas au nombre de valeurs par nœud.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une structure linéaire avec deux pointeurs par élément</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est plutôt une liste doublement<br/>
chaînée. Un arbre n'est pas linéaire mais<br/>
hiérarchique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un arbre généalogique classique des liens de parenté</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un arbre généalogique n'est pas<br/>
forcément binaire (chaque personne a au plus<br/>
deux parents directs, mais peut avoir plus de<br/>
deux enfants).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une structure hiérarchique où chaque nœud a au plus deux enfants</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : un arbre binaire est un cas<br/>
particulier d'arbre où chaque nœud a $0$, $1$ ou<br/>
$2$ enfants. La structure est récursive : chaque<br/>
enfant est lui-même la racine d'un arbre binaire.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q02 : Racine</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Combien de <strong>racines</strong> un arbre binaire possède-t-il ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'unicité de la racine définit l'arbre. Si on a<br/>
plusieurs « racines », on parle plutôt d'une<br/>
<strong>forêt</strong> (ensemble disjoint d'arbres).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un arbre non vide a toujours exactement<br/>
une racine. Seul l'arbre vide n'a pas de racine.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Exactement une</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la racine est le sommet de<br/>
l'arbre, le nœud sans parent. Tout autre nœud<br/>
descend de la racine via une chaîne unique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Cela dépend de la profondeur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : non, peu importe la profondeur, il y a<br/>
toujours une seule racine.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Plusieurs, autant que de feuilles</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : confusion entre racine et feuille. Un<br/>
arbre a une racine et plusieurs feuilles<br/>
(typiquement).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q03 : Feuille</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'est-ce qu'une <strong>feuille</strong> dans un arbre binaire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les feuilles sont importantes car elles marquent les<br/>
cas de base des algorithmes récursifs sur les arbres.<br/>
Un parcours s'arrête typiquement à chaque feuille.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La racine de l'arbre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la racine est au sommet, les feuilles<br/>
sont les nœuds <strong>terminaux</strong>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un nœud à mi-hauteur de l'arbre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune définition de feuille basée sur<br/>
la hauteur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un nœud qui a exactement deux enfants</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ça, c'est un nœud <strong>interne complet</strong>.<br/>
Une feuille n'a aucun enfant.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Un nœud qui n'a aucun enfant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : une feuille est un nœud sans<br/>
descendant. Elle marque la fin d'une branche.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q04 : Hauteur d'un arbre</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'appelle-t-on <strong>hauteur</strong> d'un arbre binaire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Variante : certaines conventions comptent en<br/>
<strong>nombre de nœuds</strong> plutôt que d'arêtes (la racine<br/>
seule a alors une hauteur de $1$). Préciser la<br/>
convention dans tout exercice.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La distance maximale séparant deux feuilles quelconques de l'arbre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le diamètre, pas la hauteur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le nombre de feuilles présentes dans tout l'arbre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le nombre de feuilles<br/>
renseigne sur la<br/>
capacité finale d'un<br/>
arbre, mais ne mesure<br/>
pas sa hauteur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Le plus long chemin de la racine à une feuille</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : convention courante, en<br/>
comptant le chemin en nombre d'<strong>arêtes</strong>. Un<br/>
arbre réduit à une racine a une hauteur de<br/>
$0$. Un arbre vide a souvent la convention de<br/>
hauteur $-1$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le nombre total de nœuds que contient l'arbre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est la <strong>taille</strong>, pas la hauteur.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q05 : Profondeur d'un nœud</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>La <strong>profondeur</strong> d'un nœud dans un arbre est :</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La hauteur de l'arbre est égale à la profondeur<br/>
maximale (parmi tous les nœuds). Les deux notions<br/>
sont liées mais distinctes.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le nombre de feuilles situées sous ce nœud</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est encore une autre quantité.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La longueur du chemin de la racine jusqu'à ce nœud</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la racine a une profondeur de<br/>
$0$, ses enfants $1$, etc. La profondeur est une<br/>
propriété du nœud, alors que la hauteur est une<br/>
propriété de l'arbre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le nombre total de descendants de ce nœud</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est plutôt la <strong>taille du sous-arbre</strong><br/>
enraciné en ce nœud.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La distance de ce nœud jusqu'à sa feuille la plus proche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas la définition standard de<br/>
profondeur.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q06 : Parcours préfixe</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans un parcours <strong>préfixe</strong> (ou <em>pre-order</em>), dans<br/>
quel ordre visite-t-on les nœuds ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Mnémotechnique : <strong>pré</strong>fixe = nœud d'<strong>abord</strong> ;<br/>
<strong>in</strong>fixe = nœud <strong>au milieu</strong> ; <strong>post</strong>fixe = nœud <strong>après</strong>. Le « préfixe », « infixe », « postfixe »<br/>
réfère à la position du nœud dans la séquence des<br/>
visites.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Nœud, sous-arbre gauche, sous-arbre droit</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : « préfixe » car on visite le nœud<br/>
<strong>avant</strong> ses enfants (préfixe = devant).<br/>
Utilisation typique : copier un arbre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Sous-arbre droit, nœud, sous-arbre gauche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ordre inhabituel, ce n'est aucun des<br/>
parcours classiques.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Sous-arbre gauche, nœud, sous-arbre droit</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le parcours <strong>infixe</strong> (in-order).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Sous-arbre gauche, sous-arbre droit, nœud</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le parcours <strong>postfixe</strong><br/>
(post-order).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q07 : Parcours infixe</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans quel ordre s'effectue un parcours <strong>infixe</strong> d'un<br/>
arbre binaire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Sur un arbre binaire de recherche, le parcours<br/>
infixe parcourt les valeurs dans l'ordre. C'est la<br/>
raison principale d'utiliser cette structure pour<br/>
maintenir un ensemble trié dynamiquement.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Nœud, sous-arbre gauche, sous-arbre droit</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le parcours <strong>préfixe</strong>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Sous-arbre gauche, sous-arbre droit, nœud</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le parcours <strong>postfixe</strong>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Sous-arbre gauche, nœud, sous-arbre droit</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on visite d'abord tout le<br/>
sous-arbre gauche, puis le nœud lui-même, puis le<br/>
sous-arbre droit. Ce parcours est très utile sur<br/>
un arbre binaire de recherche : il donne les<br/>
valeurs <strong>dans l'ordre croissant</strong>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Toutes les feuilles d'abord, puis tous les nœuds internes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun parcours classique ne sépare<br/>
ainsi.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q08 : Parcours postfixe</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Le parcours <strong>postfixe</strong> visite :</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Application : pour calculer la <strong>taille</strong> d'un arbre<br/>
ou sa <strong>hauteur</strong> récursivement, on a besoin des<br/>
résultats des sous-arbres avant le nœud courant,<br/>
c'est typiquement un parcours postfixe.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Le sous-arbre gauche, puis le sous-arbre droit, puis le nœud</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on visite le nœud <strong>après</strong> ses<br/>
enfants. Très utile pour libérer la mémoire d'un<br/>
arbre (ses feuilles d'abord) ou évaluer une<br/>
expression arithmétique en notation postfixée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Uniquement les feuilles, en ignorant les nœuds internes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : tous les nœuds sont visités, pas<br/>
seulement les feuilles.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les nœuds dans un ordre aléatoire, différent à chaque appel</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un parcours est déterministe.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>D'abord le nœud courant, puis son sous-arbre gauche, puis son sous-arbre droit</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le parcours préfixe.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q09 : Parcours en largeur</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Le parcours en <strong>largeur</strong> d'un arbre :</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Mémo : <strong>largeur = file</strong>, <strong>profondeur = pile</strong><br/>
(ou récursivité). Cette dualité est centrale dans<br/>
les algorithmes sur les graphes, dont les<br/>
parcours en largeur et en profondeur s'appuient<br/>
sur ces deux structures.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Visite la branche gauche en entier avant la droite</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est plutôt un parcours en<br/>
<strong>profondeur</strong> orienté vers la gauche.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Visite tous les nœuds à profondeur $0$, puis $1$, puis $2$, etc.</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on parcourt niveau par niveau,<br/>
de la racine vers les feuilles. Implémentation<br/>
standard : avec une <strong>file</strong>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Visite uniquement les nœuds internes, sans passer par les feuilles</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : tous les nœuds sont visités.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Évalue une expression arithmétique stockée dans l'arbre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait plutôt un parcours postfixe.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q10 : Taille d'un arbre</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>La <strong>taille</strong> d'un arbre binaire est :</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Relation utile : un arbre binaire de hauteur $h$ a<br/>
au plus $2^{h+1} - 1$ nœuds. C'est le nombre maximum,<br/>
atteint quand l'arbre est <strong>parfait</strong> (tous les niveaux<br/>
entièrement remplis, toutes les feuilles au même niveau).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le nombre d'arêtes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un arbre à $n$ nœuds a exactement<br/>
$n - 1$ arêtes, donc ce n'est pas une mesure<br/>
indépendante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La hauteur du plus long chemin</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est la <strong>hauteur</strong>, pas la taille.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Le nombre total de nœuds</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la taille compte tous les nœuds<br/>
(internes et feuilles). Pour la calculer, un<br/>
parcours récursif suffit : $T(\text{vide}) = 0$ ;<br/>
$T(\text{nœud}) = 1 + T(\text{gauche}) + T(\text{droit})$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le nombre de feuilles</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est seulement une partie des nœuds.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q11 : Implémentation Python</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour un nœud d'arbre binaire, l'implémentation la plus<br/>
claire et la plus idiomatique en Python est :</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Convention : un sous-arbre vide est représenté par<br/>
<code>None</code>. Cela simplifie la récursivité, le cas de<br/>
base est <code>if noeud is None: return ...</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une chaîne de caractères listant les valeurs des nœuds</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas adapté à une structure récursive.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un dictionnaire unique associant une clé entière à chaque nœud</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : possible mais pas idiomatique. Une<br/>
classe dédiée est plus claire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une liste de longueur fixe <code>[valeur, gauche, droite]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : possible, mais peu lisible. Une classe<br/>
dédiée est plus claire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une classe avec trois attributs : <code>valeur</code>, <code>gauche</code>, <code>droit</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est l'approche orientée objet<br/>
standard, où <code>gauche</code> et <code>droit</code> valent soit<br/>
<code>None</code>, soit un autre nœud. Exemple :</p>
<pre><code>class Noeud:
    def __init__(self, v, g=None, d=None):
        self.valeur = v
        self.gauche = g
        self.droit = d</code></pre>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q12 : Calcul récursif de la hauteur</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle fonction Python calcule correctement la hauteur<br/>
d'un arbre binaire (en nombre d'arêtes, $-1$ pour l'arbre<br/>
vide) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Convention alternative : compter en <strong>nombre de nœuds</strong> sur le chemin (cas vide → $0$). Adapter<br/>
l'arithmétique en conséquence ($\max + 1$ devient<br/>
$\max$ ou différent).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def h(n):
    return 1 + max(h(n.gauche), h(n.droit))</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il manque le <strong>cas de base</strong>. La<br/>
récursion descend sur un sous-arbre vide et<br/>
<code>n.gauche</code> est alors évalué sur <code>None</code>, ce qui<br/>
lève <code>AttributeError</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def h(n):
    if n is None: return 0
    return 1 + h(n.gauche) + h(n.droit)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on <strong>somme</strong> les hauteurs, ce qui est<br/>
incorrect. Il faut prendre le <strong>maximum</strong>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def h(n):
    if n is None: return -1
    return max(h(n.gauche), h(n.droit))</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sans le <code>1 +</code>, rien ne compte les<br/>
arêtes descendues. La fonction renvoie $-1$<br/>
pour <strong>tout</strong> arbre, vide ou non.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>def h(n):
    if n is None: return -1
    return 1 + max(h(n.gauche), h(n.droit))</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on prend la profondeur maximale<br/>
des deux sous-arbres et on ajoute $1$ (pour<br/>
l'arête vers ce nœud). Convention : arbre vide<br/>
de hauteur $-1$, racine seule de hauteur $0$.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q13 : Arbre équilibré</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'est-ce qu'un arbre binaire <strong>équilibré</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Sans équilibrage, un arbre peut dégénérer en<br/>
« peigne » (chaque nœud a un seul enfant) de<br/>
hauteur $n$ : la recherche devient alors aussi lente<br/>
qu'un parcours de liste.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un arbre dont tous les nœuds internes possèdent exactement deux enfants, sans exception</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est un arbre <strong>plein</strong> (ou localement<br/>
complet), pas équilibré.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un arbre parfaitement symétrique, aux sous-arbres gauche et droit identiques</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un arbre équilibré n'est pas<br/>
forcément symétrique. La symétrie est une<br/>
contrainte plus forte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Un arbre où les hauteurs des deux sous-arbres de chaque nœud diffèrent d'au plus $1$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : un arbre équilibré garde une hauteur de<br/>
l'ordre de $\log_2 n$ pour $n$ nœuds, ce qui rend la<br/>
recherche et l'insertion rapides dans un arbre binaire<br/>
de recherche.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un arbre où la racine se trouve au centre exact de la structure</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la racine est au sommet, pas au centre.<br/>
La notion d'« équilibre » est plus précise.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q14 : Code de parcours préfixe</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle fonction Python affiche les valeurs d'un arbre<br/>
binaire en parcours <strong>préfixe</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le seul changement entre les trois parcours en<br/>
profondeur est la <strong>position</strong> du <code>print</code> par rapport<br/>
aux deux appels récursifs. Très instructif à<br/>
observer.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>def parcours(n):
    if n is None: return
    print(n.valeur)
    parcours(n.gauche)
    parcours(n.droit)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on imprime le nœud <strong>avant</strong> ses<br/>
enfants : c'est la définition même du parcours<br/>
préfixe.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def parcours(n):
    print(n.valeur)
    parcours(n.gauche)
    parcours(n.droit)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il manque le <strong>cas de base</strong><br/>
<code>if n is None: return</code>. L'appel finit par<br/>
descendre sur <code>None</code> et lève<br/>
<code>AttributeError</code> avant la fin du parcours.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def parcours(n):
    if n is None: return
    parcours(n.gauche)
    parcours(n.droit)
    print(n.valeur)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est un parcours <strong>postfixe</strong> (nœud<br/>
après les enfants).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def parcours(n):
    if n is None: return
    parcours(n.gauche)
    print(n.valeur)
    parcours(n.droit)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le parcours <strong>infixe</strong>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q15 : Somme des valeurs d'un arbre</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un arbre binaire est construit avec la classe <code>Noeud</code>, un sous-arbre<br/>
vide valant <code>None</code> :<br/>
<pre><code>class Noeud:
    def __init__(self, valeur, gauche, droit):
        self.valeur = valeur
        self.gauche = gauche
        self.droit = droit
def somme(arbre):
    if arbre is None:
        return 0
    return arbre.valeur + somme(arbre.gauche) + somme(arbre.droit)
a = Noeud(5, Noeud(3, None, Noeud(4, None, None)), Noeud(8, None, None))</code></pre><br/>
Que renvoie <code>somme(a)</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une fonction récursive sur un arbre traite d'abord le cas de l'arbre<br/>
vide, puis combine la valeur de la racine avec les résultats des deux<br/>
sous-arbres. Ici la somme de toutes les valeurs vaut $20$.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>20</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la fonction ajoute la valeur de chaque nœud à la<br/>
somme de ses deux sous-arbres, un sous-arbre vide comptant pour $0$.<br/>
On obtient $5 + 3 + 4 + 8 = 20$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>12</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : $4 + 8 = 12$ ne compte que les feuilles. La fonction ajoute<br/>
aussi <code>arbre.valeur</code> pour chaque nœud interne, ici $5$ et $3$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>16</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : $5 + 3 + 8 = 16$ s'arrête aux enfants de la racine. Les<br/>
appels récursifs descendent jusqu'aux sous-arbres vides et comptent<br/>
aussi le nœud $4$, fils droit de $3$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, car certains sous-arbres valent <code>None</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le cas de base <code>if arbre is None</code> traite justement les<br/>
sous-arbres vides en renvoyant $0$, avant toute lecture de<br/>
<code>arbre.valeur</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q16 : Nombre de feuilles</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour un arbre binaire <strong>plein</strong> (chaque nœud interne a<br/>
exactement deux enfants), si $f$ est le nombre de<br/>
feuilles et $i$ le nombre de nœuds internes, quelle<br/>
relation a-t-on ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cette relation s'utilise pour des comptages<br/>
d'arbres dans les exercices. Elle vient d'une<br/>
symétrie structurelle : chaque nœud interne « remplace<br/>
» une feuille par lui-même plus deux nouvelles<br/>
feuilles (delta de $+1$ feuille, $+1$ interne).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune relation déterministe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il existe bien une relation pour les<br/>
arbres pleins.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>$f = i + 1$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : par récurrence sur la taille.<br/>
Cas de base : un seul nœud (racine = feuille),<br/>
$f = 1, i = 0$. Pour un arbre plus grand, chaque<br/>
nouveau nœud interne ajoute une feuille (en<br/>
remplaçant un fils null par un sous-arbre).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$f = i$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la relation est différente. On peut<br/>
montrer $f = i + 1$ par récurrence.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$f = 2 \cdot i$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ne se vérifie pas.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q17 : Implémenter un parcours en largeur</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour implémenter un parcours en largeur d'un arbre<br/>
binaire en Python, on utilise généralement :</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Code typique, avec une liste Python utilisée<br/>
comme file :</p>
<pre><code>def parcours_largeur(racine):
    if racine is None:
        return
    f = [racine]
    while len(f) &gt; 0:
        n = f.pop(0)
        print(n.valeur)
        if n.gauche is not None:
            f.append(n.gauche)
        if n.droit is not None:
            f.append(n.droit)</code></pre>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une file (<code>list</code> avec <code>append</code> et <code>pop(0)</code>)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on enfile la racine, puis tant<br/>
que la file n'est pas vide on défile le nœud<br/>
courant (<code>pop(0)</code> retire le premier élément) et<br/>
on enfile ses deux enfants. La file assure le<br/>
traitement niveau par niveau.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une simple variable mémorisant le nœud courant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : insuffisant pour stocker plusieurs<br/>
nœuds en attente.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une pile (<code>list</code> avec <code>append</code> et <code>pop</code>)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la pile correspond au parcours en<br/>
<strong>profondeur</strong>. Pour la largeur, c'est différent.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un dictionnaire trié par valeur de nœud</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas adapté.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q18 : Borne du nombre de nœuds</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel est le nombre <strong>maximum</strong> de nœuds d'un arbre<br/>
binaire de hauteur $h$, la hauteur étant comptée<br/>
en nombre d'arêtes (un arbre réduit à sa racine a<br/>
une hauteur 0) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Conséquence : pour avoir $n$ nœuds dans un arbre<br/>
équilibré, la hauteur est de l'ordre de $\log_2 n$.<br/>
C'est ce qui rend les arbres de recherche si<br/>
efficaces : opérations en $O(\log n)$.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$h + 1$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le nombre <strong>minimum</strong> (arbre en<br/>
peigne).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$h^2$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la croissance n'est pas polynomiale<br/>
mais exponentielle (en hauteur).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$2^h - 1$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur d'une unité dans l'exposant : $2^h - 1$<br/>
est le nombre maximal de nœuds d'un arbre de<br/>
hauteur $h - 1$. Avec la convention « hauteur =<br/>
nombre d'arêtes », un arbre parfait de hauteur<br/>
$h$ possède $h + 1$ niveaux, soit $2^{h+1} - 1$<br/>
nœuds.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>$2^{h+1} - 1$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : un arbre <strong>parfait</strong> de hauteur<br/>
$h$ a $1 + 2 + 4 + \ldots + 2^h = 2^{h+1} - 1$<br/>
nœuds. C'est le maximum atteignable.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q20 : Arbre miroir</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour calculer le <strong>miroir</strong> d'un arbre binaire<br/>
(échanger gauche et droite à chaque nœud), une approche<br/>
récursive est :</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>C'est un exemple typique d'algorithme récursif<br/>
simple sur arbre. La récursion est naturelle car la<br/>
structure est elle-même récursive.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Échanger uniquement la racine de l'arbre avec sa dernière feuille</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas suffisant. Il faut le faire à<br/>
<strong>chaque</strong> nœud, récursivement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Échanger les deux sous-arbres de chaque nœud, récursivement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on inverse à tous les niveaux.<br/>
En Python :</p>
<pre><code>def miroir(n):
    if n is None: return
    n.gauche, n.droit = n.droit, n.gauche
    miroir(n.gauche)
    miroir(n.droit)</code></pre>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Ne rien faire, l'arbre reste inchangé par symétrie</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ne donne pas le miroir.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Trier les valeurs des nœuds par ordre décroissant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun rapport avec le tri.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q21 : Complexité de la recherche</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans un arbre binaire <strong>non ordonné</strong> de $n$ nœuds, la<br/>
recherche d'une valeur a une complexité au pire de :</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>C'est précisément la motivation des <strong>arbres binaires de recherche</strong>, qui en ajoutant la<br/>
propriété d'ordre, ramènent la recherche à<br/>
$O(\log n)$ en moyenne (et $O(\log n)$ garanti si<br/>
équilibré).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$O(\log n)$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait dans un arbre <strong>ordonné</strong><br/>
équilibré (arbre binaire de recherche<br/>
équilibré). Sans ordre, on doit<br/>
parcourir.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>$O(n)$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : sans propriété d'ordre, on doit<br/>
potentiellement visiter tous les nœuds. Aucun<br/>
gain par rapport à une liste.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$O(n^2)$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : excessif. Un simple parcours visite<br/>
chaque nœud une fois, donc $O(n)$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$O(\sqrt{n})$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune raison particulière.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q24 : Comparer deux arbres récursivement</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Avec la classe <code>Noeud</code> habituelle (attributs <code>valeur</code>, <code>gauche</code> et<br/>
<code>droit</code>, un sous-arbre vide valant <code>None</code>), cette fonction teste si<br/>
deux arbres sont identiques :</p>
<pre><code>def egaux(a, b):
    if a is None and b is None:
        return True
    if a is None or b is None:
        return False
    return (a.valeur == b.valeur and egaux(a.gauche, b.gauche)
            and egaux(a.droit, b.droit))</code></pre>
<p>Que se passe-t-il si l'on supprime le second test,<br/>
<code>if a is None or b is None</code>, et la ligne qui le suit ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une fonction récursive sur deux arbres doit prévoir tous les cas de<br/>
base : les deux arbres vides, un seul vide. Oublier le cas d'un seul<br/>
arbre vide conduit à lire un attribut de <code>None</code>, ce qui provoque une<br/>
erreur.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La fonction reste correcte : ce second test était redondant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le premier test ne traite que le cas où les deux arbres sont<br/>
vides. Si un seul l'est, l'exécution atteint <code>a.valeur == b.valeur</code><br/>
avec <code>None</code> d'un côté.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La fonction renvoie toujours <code>True</code>, les formes n'étant plus comparées</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la fonction compare toujours les valeurs et renvoie <code>False</code><br/>
dès que deux valeurs diffèrent. C'est le cas d'un seul sous-arbre<br/>
vide qui n'est plus traité.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une erreur survient quand un seul des deux sous-arbres comparés est vide</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : si <code>a</code> vaut <code>None</code> et pas <code>b</code>, ou l'inverse, le<br/>
premier test échoue et Python lit l'attribut <code>valeur</code> de <code>None</code>, ce<br/>
qui lève <code>AttributeError</code>. Si une différence de valeur est repérée<br/>
avant, <code>and</code> s'arrête et la fonction renvoie <code>False</code> sans erreur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les appels récursifs ne s'arrêtent plus et lèvent <code>RecursionError</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : chaque appel descend d'un niveau dans les deux arbres, qui<br/>
sont finis. Les appels s'arrêtent soit sur deux sous-arbres vides,<br/>
soit sur une erreur dès qu'un seul l'est.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q25 : Cas d'usage des arbres binaires</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Lequel des cas suivants utilise typiquement un arbre<br/>
binaire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Autres usages : analyse syntaxique (arbres de<br/>
syntaxe abstraite), systèmes de fichiers (chaque<br/>
dossier est un nœud), arbres de jeux (échecs, go),<br/>
structures de regroupement hiérarchique. Les arbres<br/>
sont omniprésents en informatique.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Stocker une simple liste de courses du quotidien, sans aucun ordre particulier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une liste plate suffit. Pas besoin<br/>
d'arbre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Échanger le contenu de deux variables d'un programme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'échange de deux variables<br/>
se fait avec une variable<br/>
temporaire (ou une affectation<br/>
multiple en Python). Cela n'a<br/>
aucun lien avec une structure<br/>
arborescente.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Compter le nombre total de mots dans un texte</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pour compter des mots,<br/>
un simple compteur entier<br/>
suffit. Un arbre serait<br/>
totalement disproportionné<br/>
pour cette tâche.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Représenter une expression arithmétique ou un arbre de décision</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : ces cas exploitent la nature<br/>
hiérarchique et/ou récursive de l'arbre. Autre<br/>
usage majeur, l'index ordonné (arbre binaire<br/>
de recherche), qui maintient un ensemble trié<br/>
avec insertion/suppression dynamiques.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q26 : Calcul récursif de la taille</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle fonction Python calcule correctement la<br/>
<strong>taille</strong> (nombre total de nœuds) d'un arbre<br/>
binaire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cette structure de récursion (cas de base<br/>
<code>None</code> → $0$, cas récursif $1 + $ somme des<br/>
sous-arbres) est l'archétype de l'algorithme<br/>
récursif sur arbre binaire. Elle s'adapte à<br/>
d'autres mesures (somme des valeurs, produit,<br/>
maximum, etc.) en changeant la combinaison.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def taille(n):
    if n is None:
        return 0
    return 1 + max(taille(n.gauche), taille(n.droit))</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on prend ici le <strong>maximum</strong> au lieu de<br/>
la <strong>somme</strong>. Le résultat correspond à la<br/>
hauteur (en nombre de nœuds), pas à la taille.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>def taille(n):
    if n is None:
        return 0
    return 1 + taille(n.gauche) + taille(n.droit)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on additionne $1$ (pour le nœud<br/>
courant) à la somme des tailles des deux<br/>
sous-arbres. Le cas de base est l'arbre vide,<br/>
de taille $0$. Récursion classique sur la<br/>
structure d'arbre, en $O(n)$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def taille(n):
    if n is None:
        return 1
    return taille(n.gauche) + taille(n.droit)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on compte les <strong>feuilles vides</strong><br/>
(<code>None</code>) au lieu des nœuds. La taille d'un<br/>
arbre à un seul nœud serait $2$ au lieu de<br/>
$1$, ce qui est faux.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def taille(n):
    if n is None:
        return 0
    return taille(n.gauche) + taille(n.droit)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on oublie de compter le nœud<br/>
courant (pas de <code>1 +</code>). La somme se réduit<br/>
de proche en proche à des cas de base<br/>
valant $0$ : la fonction renvoie $0$ pour<br/>
<strong>tout</strong> arbre.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q27 : Compter les feuilles</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle fonction Python compte correctement le<br/>
nombre de <strong>feuilles</strong> d'un arbre binaire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cas particulier dans le code : on doit reconnaître<br/>
explicitement les feuilles avec<br/>
<code>n.gauche is None and n.droit is None</code>. C'est une<br/>
différence importante par rapport à la fonction<br/>
<code>taille</code>, qui se contente d'additionner sans<br/>
distinguer les feuilles.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def feuilles(n):
    if n is None:
        return 1
    return feuilles(n.gauche) + feuilles(n.droit)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on compte les positions vides<br/>
(<code>None</code>), ce qui donne le double du nombre de<br/>
feuilles plus quelque chose pour les nœuds à<br/>
un seul enfant. Pas la bonne mesure.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def feuilles(n):
    if n is None:
        return 0
    return feuilles(n.gauche) + feuilles(n.droit)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il manque le cas où le nœud est une<br/>
feuille. Cette fonction renverrait toujours<br/>
$0$ car on ne compte jamais. Récursion<br/>
stérile.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def feuilles(n):
    if n is None:
        return 0
    return 1 + feuilles(n.gauche) + feuilles(n.droit)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on ajoute $1$ pour <strong>chaque</strong> nœud,<br/>
ce qui compte la <strong>taille totale</strong> de l'arbre,<br/>
pas seulement les feuilles. Il faut distinguer<br/>
les feuilles (sans enfant) des nœuds internes<br/>
(au moins un enfant).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>def feuilles(n):
    if n is None:
        return 0
    if n.gauche is None and n.droit is None:
        return 1
    return feuilles(n.gauche) + feuilles(n.droit)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : trois cas. (1) Arbre vide :<br/>
aucune feuille. (2) Nœud sans enfant : une<br/>
feuille. (3) Nœud interne : on additionne les<br/>
feuilles des deux sous-arbres. C'est le<br/>
patron classique de comptage récursif.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q28 : Profondeur d'un nœud</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment calculer la <strong>profondeur</strong> d'un nœud<br/>
contenant la valeur <code>cible</code> dans un arbre binaire<br/>
(ou <code>-1</code> si la valeur n'est pas présente) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Variante intéressante : utiliser un parcours en<br/>
largeur avec une file qui contient les couples<br/>
<code>(nœud, profondeur)</code>. Permet d'éviter la<br/>
récursion. Complexité dans les deux cas :<br/>
<code>O(n)</code> au pire, où <code>n</code> est le nombre de nœuds.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def profondeur(n, cible):
    if n is None:
        return -1
    if n.valeur == cible:
        return 0
    g = profondeur(n.gauche, cible)
    if g != -1:
        return g + 1
    return 1 + profondeur(n.droit, cible)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le cas « absent » n'est pas propagé.<br/>
Si la cible n'est ni à gauche ni à droite, la<br/>
dernière ligne renvoie $1 + (-1)$, c'est-à-dire<br/>
$0$, que l'appelant prend pour une profondeur<br/>
valide. Une valeur absente de l'arbre reçoit<br/>
alors une profondeur fantaisiste au lieu de<br/>
<code>-1</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def profondeur(n, cible):
    if n.valeur == cible:
        return 0
    return 1 + profondeur(n.gauche, cible)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on ne descend que dans le sous-arbre<br/>
<strong>gauche</strong>, et on plante si on atteint un<br/>
nœud <code>None</code> sans avoir trouvé la cible.<br/>
L'arbre ne se réduit pas à sa branche gauche.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def profondeur(n, cible):
    if n is None:
        return 0
    if n.valeur == cible:
        return 1
    return profondeur(n.gauche, cible) + profondeur(n.droit, cible)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on <strong>additionne</strong> les résultats des<br/>
deux sous-arbres, ce qui n'a pas de sens pour<br/>
une profondeur. De plus, on ne propage pas<br/>
le compteur de profondeur, donc on ne peut<br/>
pas savoir à quelle distance se trouve la<br/>
cible.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>def profondeur(n, cible, p=0):
    if n is None:
        return -1
    if n.valeur == cible:
        return p
    g = profondeur(n.gauche, cible, p + 1)
    if g != -1:
        return g
    return profondeur(n.droit, cible, p + 1)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on transmet la profondeur<br/>
courante via le paramètre <code>p</code>, qu'on incrémente<br/>
à chaque descente récursive. On retourne <code>p</code><br/>
dès que la cible est trouvée. Si la recherche<br/>
dans le sous-arbre gauche échoue (<code>-1</code>), on<br/>
essaie le droit. Sinon on remonte <code>-1</code> (cible<br/>
absente).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q29 : Les sous-arbres d'un nœud</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Combien de sous-arbres un nœud d'arbre binaire possède-t-il ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un arbre binaire est soit vide, soit un nœud muni d'un sous-arbre<br/>
gauche et d'un sous-arbre droit, eux-mêmes binaires.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Deux, le gauche et le droit, éventuellement vides</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la définition récursive donne à chaque nœud<br/>
exactement deux sous-arbres ordonnés ; une feuille a deux<br/>
sous-arbres vides.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un seul, le second n'étant qu'une option</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les deux positions, gauche et droite, existent<br/>
toujours, même vides.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Deux au minimum, un arbre binaire étant toujours complet</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : rien n'impose que les deux sous-arbres soient non<br/>
vides.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Autant que l'on veut, pourvu qu'ils soient ordonnés</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est la définition d'un arbre général, pas d'un<br/>
arbre binaire.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q30 : Un arbre réduit à une chaîne</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans un arbre binaire de $n$ nœuds, chaque nœud a au plus un<br/>
enfant. Que peut-on dire de cet arbre ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La forme d'un arbre binaire va de la chaîne, hauteur $n$, à l'arbre<br/>
équilibré, hauteur $\log n$ : c'est elle qui fixe le coût des<br/>
parcours de la racine à une feuille.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Il est filiforme, de hauteur maximale pour $n$ nœuds</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : les nœuds forment une seule chaîne de la racine<br/>
à l'unique feuille ; la hauteur est la plus grande possible,<br/>
comme pour une liste chaînée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il est équilibré, chaque nœud ayant au plus un enfant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un arbre équilibré répartit les nœuds entre les deux<br/>
côtés ; ici tout est d'un seul côté à chaque niveau.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Ce n'est pas un arbre binaire, chaque nœud devant avoir deux enfants</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un sous-arbre vide est permis, l'arbre est bien<br/>
binaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Sa hauteur est de l'ordre de $\log n$, comme toujours</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est la hauteur d'un arbre équilibré ; ici elle est<br/>
de l'ordre de $n$.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q31 : Compter les nœuds internes</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un arbre binaire compte $7$ nœuds, dont $4$ feuilles. Combien<br/>
a-t-il de nœuds internes ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Feuilles et nœuds internes forment une partition des nœuds : les<br/>
compter l'un donne l'autre.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>$3$, les nœuds qui ne sont pas des feuilles</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : un nœud est soit une feuille, soit un nœud<br/>
interne ; $7 - 4 = 3$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$4$, autant que de feuilles exactement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : rien n'impose l'égalité ; on retire les feuilles du<br/>
total.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$6$, tous les nœuds sauf la racine</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la racine est un nœud interne dès qu'elle a un<br/>
enfant, et les feuilles n'en sont pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$1$, la racine étant le seul nœud interne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : tout nœud ayant au moins un enfant est interne, pas<br/>
seulement la racine.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q32 : L'arbre vide</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>L'arbre vide, sans aucun nœud, est-il un arbre binaire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Taille nulle, aucune feuille : l'arbre vide est le point de départ<br/>
de toutes les mesures récursives.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Oui, c'est le cas de base des définitions récursives</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : tout sous-arbre absent est un arbre vide, et<br/>
les fonctions récursives sur les arbres commencent par le<br/>
traiter.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Non, un arbre a toujours au moins une racine</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sans arbre vide, impossible de dire ce qu'est le<br/>
sous-arbre gauche d'une feuille.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Oui, mais seulement comme sous-arbre d'une feuille</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'arbre vide existe aussi seul, par exemple avant la<br/>
première insertion.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Non, il s'agit d'une liste vide et non d'un arbre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la structure vide de chaque type existe, liste vide,<br/>
pile vide, arbre vide.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q33 : Un arbre représenté par des tuples imbriqués</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un arbre est représenté par le tuple <code>(gauche, valeur, droit)</code>,<br/>
un sous-arbre vide étant <code>None</code>. Que vaut <code>a[2][1]</code> ?<br/>
<pre><code>a = ((None, 2, None), 5, (None, 8, None))</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Avec des tuples, descendre dans l'arbre revient à enchaîner les<br/>
indices : $0$ pour la gauche, $1$ pour la valeur, $2$ pour la<br/>
droite.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>8</code>, la valeur du fils droit</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>a[2]</code> est le sous-arbre droit<br/>
<code>(None, 8, None)</code>, et son élément d'indice $1$ est sa<br/>
valeur, <code>8</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>5</code>, la valeur de la racine</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la valeur de la racine est <code>a[1]</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>2</code>, la valeur du fils gauche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le fils gauche est <code>a[0]</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, un tuple ne s'indexant pas deux fois</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>a[2]</code> est lui-même un tuple, on peut l'indexer à son<br/>
tour.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q34 : Reconnaître une feuille</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un nœud est un objet de classe <code>Noeud</code> avec les attributs<br/>
<code>valeur</code>, <code>gauche</code> et <code>droit</code>, un sous-arbre vide étant <code>None</code>.<br/>
Quelle expression indique que <code>n</code> est une feuille ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Feuille et arbre vide se distinguent : la feuille est un nœud sans<br/>
enfant, l'arbre vide n'est pas un nœud.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>n.gauche is None and n.droit is None</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : une feuille n'a aucun enfant, les deux liens<br/>
doivent être absents.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>n.gauche is None or n.droit is None</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un nœud avec un seul enfant vérifie cette condition<br/>
sans être une feuille.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>n.valeur is None</code>, la feuille ne portant rien</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la valeur d'une feuille est une donnée ordinaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>n is None</code>, le nœud étant au bout de l'arbre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>None</code> est l'arbre vide, pas une feuille.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q35 : Lire une fonction récursive sur un arbre</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que calcule cette fonction, pour un arbre de nœuds <code>Noeud</code> dont<br/>
les sous-arbres vides sont <code>None</code> ?<br/>
<pre><code>def compte(a):
    if a is None:
        return 0
    n = compte(a.gauche) + compte(a.droit)
    if a.gauche is not None and a.droit is not None:
        n = n + 1
    return n</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Lire une fonction récursive sur un arbre, c'est repérer ce qui est<br/>
ajouté à chaque nœud et à quelle condition.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Le nombre de nœuds ayant exactement deux enfants</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : chaque nœud ajoute $1$ au total de ses<br/>
sous-arbres seulement si ses deux enfants existent.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le nombre de feuilles, nœuds sans enfant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une feuille a ses deux liens à <code>None</code>, elle n'ajoute<br/>
rien.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La taille de l'arbre, son nombre de nœuds</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la taille ajouterait $1$ pour tout nœud, sans<br/>
condition.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le nombre de nœuds internes, à un ou deux enfants</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un nœud à un seul enfant est interne mais n'est pas<br/>
compté.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q36 : Ordre infixe d'un arbre décrit en mots</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>La racine porte <code>A</code>. Son fils gauche <code>B</code> a deux enfants,<br/>
<code>D</code> à gauche et <code>E</code> à droite. Son fils droit <code>C</code> a un<br/>
seul enfant, <code>F</code>, à gauche. Quel est le parcours infixe ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les trois parcours en profondeur ne diffèrent que par la place du<br/>
nœud par rapport à ses deux sous-arbres.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>D B E A F C</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : infixe signifie sous-arbre gauche, nœud,<br/>
sous-arbre droit, appliqué récursivement : <code>D B E</code>,<br/>
puis <code>A</code>, puis <code>F C</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>A B D E C F</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le parcours préfixe, le nœud avant ses<br/>
sous-arbres.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>D E B F C A</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le parcours postfixe, le nœud après ses<br/>
sous-arbres.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>A B C D E F</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le parcours en largeur, niveau par niveau.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q37 : Retrouver un arbre à partir de deux parcours</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un arbre binaire de trois nœuds a pour parcours préfixe<br/>
<code>A B C</code> et pour parcours infixe <code>B A C</code>. Quel est<br/>
cet arbre ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le préfixe donne la racine, l'infixe sépare ce qui est à gauche de<br/>
ce qui est à droite : les deux parcours ensemble déterminent<br/>
l'arbre.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Racine <code>A</code>, fils gauche <code>B</code>, fils droit <code>C</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : le préfixe commence par la racine, <code>A</code> ; dans<br/>
l'infixe, ce qui précède <code>A</code> est à gauche, <code>B</code>, et ce qui<br/>
suit est à droite, <code>C</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Racine <code>B</code>, fils gauche <code>A</code>, fils droit <code>C</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le premier nœud du parcours préfixe est la racine,<br/>
<code>A</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Racine <code>A</code>, fils gauche <code>C</code>, fils droit <code>B</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le parcours infixe placerait alors <code>C</code> avant <code>A</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Racine <code>C</code>, fils gauche <code>B</code>, fils droit <code>A</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>C</code> est le dernier du préfixe, il ne peut pas être<br/>
la racine.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q38 : Les feuilles d'un arbre aux niveaux pleins</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un arbre binaire a $3$ niveaux, tous pleins. Combien de feuilles<br/>
compte-t-il ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Dans un arbre aux niveaux pleins, chaque niveau double le<br/>
précédent : la moitié des nœuds, à un près, sont des feuilles.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>$4$, le dernier niveau entier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : le niveau $k$ contient $2^{k-1}$ nœuds ; les<br/>
feuilles sont les $2^{2} = 4$ nœuds du dernier niveau.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$7$, tous les nœuds de l'arbre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : $7$ est le nombre total de nœuds, dont seuls ceux du<br/>
dernier niveau sont des feuilles.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$8$, le double du dernier niveau</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : $2^{3}$ serait le niveau suivant, qui n'existe pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$3$, une seule par niveau</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les feuilles sont toutes au dernier niveau, pas une<br/>
par niveau.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires — Q39 : Feuilles et nœuds à deux enfants</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans un arbre binaire, chaque nœud interne a exactement deux<br/>
enfants. L'arbre compte $4$ nœuds internes. Combien a-t-il de<br/>
feuilles ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Dans un arbre binaire où tout nœud interne a deux enfants, le<br/>
nombre de feuilles dépasse de un le nombre de nœuds internes : un<br/>
résultat qui se prouve par récurrence sur la taille.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>$5$, une de plus que de nœuds internes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : l'arbre réduit à une feuille vérifie la<br/>
relation ; remplacer une feuille par un nœud à deux enfants<br/>
ajoute un interne et une feuille nette. D'où $4 + 1 = 5$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$8$, deux feuilles par nœud interne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les enfants d'un nœud interne sont souvent eux-mêmes<br/>
internes, pas des feuilles.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$4$, autant que de nœuds internes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il y en a toujours une de plus.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$3$, une de moins que de nœuds internes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le sens de la différence est inversé.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
