<?xml version="1.0" encoding="UTF-8"?>
<quiz>
<question type="category">
  <category>
    <text>$course$/QCM de NSI/Terminale/Arbres binaires de recherche</text>
  </category>
  <info format="html">
    <text><![CDATA[<p>Propriété d'ordre dans un arbre binaire de<br/>
recherche, opérations de recherche, d'insertion et<br/>
de suppression, complexité dans le meilleur et<br/>
dans le pire cas, équilibrage, applications aux<br/>
ensembles ordonnés dynamiques et aux dictionnaires<br/>
triés.</p>]]></text>
  </info>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q01 : Propriété fondamentale</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la <strong>propriété fondamentale</strong> d'un<br/>
arbre binaire de recherche ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les arbres binaires de recherche permettent de<br/>
maintenir un ensemble ordonné dynamique, en<br/>
offrant des opérations de recherche,<br/>
d'insertion et de suppression efficaces lorsque<br/>
l'arbre reste é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>Toutes les feuilles se trouvent au même niveau</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette description correspond à un arbre<br/>
parfait, et non à un arbre binaire de<br/>
recherche. Un arbre binaire de recherche<br/>
se définit par une propriété d'ordre, pas<br/>
par la position de ses feuilles.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Chaque nœud possède exactement deux enfants</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette description correspond à un arbre<br/>
plein, qui n'a aucun rapport direct avec<br/>
l'ordre des valeurs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Pour chaque nœud, toutes les valeurs du sous-arbre gauche sont strictement inférieures à la valeur du nœud, et toutes celles du sous-arbre droit lui sont strictement supérieures</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est la propriété d'ordre qui rend la<br/>
recherche efficace en O(\log n) dans un<br/>
arbre équilibré. Cette propriété doit être<br/>
vérifiée pour <strong>chaque</strong> nœud de l'arbre, et<br/>
non uniquement pour la racine.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La racine contient la plus grande valeur de l'arbre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette propriété correspond à la définition<br/>
d'un tas (de type maximum), pas à celle<br/>
d'un arbre binaire de recherche. Dans un<br/>
arbre binaire de recherche, la racine peut<br/>
être n'importe quelle valeur.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q02 : Complexité de la recherche</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans un arbre binaire de recherche <strong>équilibré</strong><br/>
contenant n éléments, quelle est la complexité<br/>
de la recherche d'une valeur ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cette efficacité explique pourquoi les arbres<br/>
binaires de recherche sont utilisés pour<br/>
implémenter des ensembles et dictionnaires<br/>
triés. Cette complexité dépend néanmoins<br/>
crucialement du fait que l'arbre reste<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(n²)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Aucune raison d'avoir une complexité<br/>
quadratique pour une simple recherche dans<br/>
un arbre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(1)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On ne peut pas accéder à un élément<br/>
quelconque en temps constant dans un arbre<br/>
binaire de recherche. La complexité dépend<br/>
au moins de la hauteur de l'arbre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette complexité correspond au pire cas<br/>
d'un arbre dégénéré en peigne. Pour un<br/>
arbre équilibré, on fait nettement mieux.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>O(\log n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>À chaque comparaison, on élimine la moitié<br/>
des nœuds (on descend dans le sous-arbre<br/>
gauche ou dans le sous-arbre droit). Le<br/>
nombre d'étapes est donc proportionnel à<br/>
la hauteur de l'arbre, qui vaut<br/>
O(\log n) lorsque l'arbre est équilibré.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q03 : Cas pire</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la complexité de la recherche dans<br/>
un arbre binaire de recherche dans le <strong>pire<br/>
cas</strong>, sans contrainte d'équilibrage ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Ce phénomène de dégénérescence motive<br/>
l'utilisation d'arbres binaires de recherche<br/>
auto-équilibrés (de type AVL ou rouge-noir),<br/>
qui maintiennent une hauteur en O(\log n)<br/>
grâce à des opérations de rééquilibrage à<br/>
chaque insertion ou suppression.</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(√n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Aucune raison particulière n'amène à une<br/>
complexité de cette forme dans un arbre<br/>
binaire de recherche.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(\log n) dans tous les cas</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Sans équilibrage, l'arbre peut dégénérer.<br/>
La complexité O(\log n) n'est garantie<br/>
que si l'arbre reste équilibré.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n²)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Même dans le pire cas, la recherche reste<br/>
en O(n). La hauteur de l'arbre, qui peut<br/>
atteindre n, est en cause, mais la<br/>
complexité ne devient pas quadratique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>O(n), lorsque l'arbre a dégénéré en peigne et que chaque nœud n'a qu'un enfant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Si l'on insère par exemple les valeurs<br/>
1, 2, 3, \ldots, n dans l'ordre, l'arbre<br/>
devient une liste chaînée par la droite.<br/>
La recherche y est alors en O(n), comme<br/>
dans un parcours linéaire.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q04 : Parcours infixe</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que donne un parcours <strong>infixe</strong> sur un arbre<br/>
binaire de recherche ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cette propriété permet de transformer un<br/>
arbre binaire de recherche en un tableau<br/>
trié en O(n). C'est aussi pour cette raison<br/>
que cette structure est naturelle pour<br/>
maintenir un ensemble ordonné.</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>Les valeurs dans un ordre aléatoire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un parcours d'arbre est strictement<br/>
déterministe : il ne fait jamais appel au<br/>
hasard.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Les valeurs dans l'ordre croissant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est précisément la propriété remarquable<br/>
des arbres binaires de recherche. Le<br/>
parcours infixe (sous-arbre gauche, racine,<br/>
sous-arbre droit) visite naturellement les<br/>
valeurs dans l'ordre croissant.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les valeurs dans l'ordre décroissant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pour obtenir l'ordre décroissant, il<br/>
faudrait inverser le parcours infixe en<br/>
visitant d'abord le sous-arbre droit, puis<br/>
la racine, puis le sous-arbre gauche.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune valeur particulière n'est visitée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un parcours visite chaque nœud exactement<br/>
une fois. Toutes les valeurs sont donc<br/>
parcourues.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q05 : Insertion</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour insérer une valeur v dans un arbre<br/>
binaire de recherche, on procède de la manière<br/>
suivante :</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'insertion s'effectue en O(h), où h est<br/>
la hauteur de l'arbre. Lorsque l'arbre est<br/>
équilibré, on a h = O(\log n). Sinon, dans<br/>
le pire cas, l'insertion peut atteindre<br/>
O(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="100" format="html">
    <text><![CDATA[<p>On descend dans l'arbre en comparant la valeur avec chaque nœud rencontré, puis on l'insère comme nouvelle feuille à la place vide trouvée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Si la valeur v est plus petite que celle<br/>
du nœud courant, on descend dans le<br/>
sous-arbre gauche ; sinon dans le<br/>
sous-arbre droit. On répète jusqu'à<br/>
rencontrer une place vide, où l'on crée<br/>
une nouvelle feuille.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>On trie les valeurs, puis on la place</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'insertion est une opération locale qui<br/>
préserve l'invariant d'ordre. Aucun tri<br/>
global n'est nécessaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>On la place toujours à la racine</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Insérer la nouvelle valeur à la racine<br/>
briserait la propriété d'ordre. L'insertion<br/>
doit au contraire respecter la structure<br/>
existante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>On la place dans la première feuille rencontrée, sans comparaison</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Sans comparaison avec la valeur des nœuds,<br/>
la propriété d'ordre serait violée et<br/>
l'arbre cesserait d'être un arbre binaire<br/>
de recherche.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q06 : Suppression</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>La <strong>suppression</strong> d'un nœud dans un arbre<br/>
binaire de recherche est plus délicate que<br/>
l'insertion. Pourquoi ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le cas le plus délicat est celui d'un nœud à<br/>
deux enfants. Le successeur infixe se trouve<br/>
facilement : il s'agit du nœud le plus à<br/>
gauche dans le sous-arbre droit du nœud à<br/>
supprimer.</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>Parce qu'il faut détruire l'arbre puis le reconstruire entièrement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette opération serait inutilement<br/>
coûteuse. La suppression peut se faire de<br/>
manière purement locale.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Parce que selon que le nœud à supprimer a 0, 1 ou 2 enfants, le traitement est différent, et le cas à deux enfants demande de remplacer le nœud par son successeur (ou son prédécesseur)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On distingue trois cas. Si le nœud est une<br/>
feuille, on le supprime simplement. S'il a<br/>
un seul enfant, on remplace le nœud par<br/>
cet enfant. S'il a deux enfants, on le<br/>
remplace par le <strong>successeur infixe</strong><br/>
(plus petit du sous-arbre droit) ou par le<br/>
<strong>prédécesseur infixe</strong> (plus grand du<br/>
sous-arbre gauche), puis on supprime ce<br/>
successeur (qui a au plus un enfant).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce qu'il faut entièrement re-trier l'arbre après chaque suppression</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Aucun tri global n'est nécessaire.<br/>
L'opération reste locale, mais doit<br/>
distinguer plusieurs cas selon la<br/>
structure du nœud supprimé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce qu'il est impossible de supprimer un nœud dans un arbre binaire de recherche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La suppression est tout à fait possible.<br/>
Elle est simplement plus complexe que<br/>
l'insertion, en raison de la distinction<br/>
de cas.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q07 : Comparaison avec un tableau trié</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel est l'<strong>avantage</strong> d'un arbre binaire de<br/>
recherche équilibré par rapport à un tableau<br/>
trié ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le compromis est clair. Si l'on a beaucoup de<br/>
recherches mais peu d'insertions, le tableau<br/>
trié peut suffire. Pour un mélange dynamique<br/>
d'opérations, l'arbre binaire de recherche<br/>
équilibré est mieux adapté.</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 recherche y est plus rapide</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La recherche dichotomique dans un tableau<br/>
trié est elle aussi en O(\log n). Les<br/>
deux structures sont équivalentes pour la<br/>
recherche.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune différence n'existe entre les deux structures</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les deux structures se distinguent<br/>
précisément par leur comportement face<br/>
aux opérations dynamiques d'ajout et de<br/>
suppression.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>L'insertion et la suppression y sont en O(\log n), alors qu'elles coûtent O(n) dans un tableau trié, à cause du décalage des éléments</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est le principal atout d'un arbre<br/>
binaire de recherche équilibré. On peut y<br/>
maintenir un ensemble trié dynamique avec<br/>
toutes les opérations en O(\log n),<br/>
alors qu'une insertion ou une suppression<br/>
au milieu d'un tableau trié coûte O(n).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il consomme moins de mémoire qu'un tableau</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Au contraire, un arbre binaire de<br/>
recherche consomme en général plus de<br/>
mémoire qu'un tableau, en raison des<br/>
références entre nœuds.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q08 : Construire l'arbre</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On insère successivement les valeurs 5, 3,<br/>
7, 1, 4 dans un arbre binaire de<br/>
recherche initialement vide. Que devient la<br/>
racine ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'ordre d'insertion détermine la forme de<br/>
l'arbre. Insérer dans l'ordre 1, 3, 4, 5, 7<br/>
donnerait un peigne à droite (cas dégénéré).<br/>
C'est précisément pour cette raison que les<br/>
structures auto-équilibrantes sont<br/>
importantes en pratique.</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</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La première valeur insérée devient la<br/>
racine. Toutes les insertions suivantes<br/>
deviennent des descendants de cette<br/>
racine.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>7</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La valeur 7 est plus grande que 5,<br/>
donc elle est insérée à droite de la<br/>
racine, mais elle ne devient pas la<br/>
racine elle-même.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>1</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La valeur 1 est insérée en dernier et<br/>
finit en feuille à gauche. La racine est<br/>
toujours la <strong>première</strong> valeur insérée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>4</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La valeur 4 est plus petite que 5<br/>
mais plus grande que 3. Elle finit<br/>
comme enfant droit de 3, et n'occupe<br/>
pas la racine.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q09 : Cas d'usage</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Lequel des cas suivants est un usage typique<br/>
d'un arbre binaire de recherche ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>En pratique, de nombreuses bibliothèques<br/>
utilisent des arbres auto-équilibrés pour<br/>
implémenter des ensembles et dictionnaires<br/>
triés. C'est le cas par exemple de TreeSet<br/>
et TreeMap en Java, ou de std::set et<br/>
std::map en C++.</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>Maintenir dynamiquement un ensemble trié de valeurs avec des ajouts, des suppressions et des recherches fréquentes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est l'usage emblématique. On peut par<br/>
exemple gérer une liste de scores triés<br/>
en temps réel, ou un dictionnaire dont<br/>
les clés doivent rester ordonnées.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Compter le nombre de mots dans un texte</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un compteur simple suffit pour cette<br/>
tâche. L'utilisation d'un arbre binaire<br/>
de recherche serait disproportionnée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Afficher une image</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'affichage d'une image n'a aucun rapport<br/>
avec la structure d'arbre binaire de<br/>
recherche.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Calculer la somme des éléments d'une liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un parcours linéaire de la liste suffit.<br/>
Aucune structure ordonnée n'est<br/>
nécessaire.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q10 : Recherche récursive</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle fonction Python recherche correctement<br/>
la valeur v dans un arbre binaire de<br/>
recherche ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>C'est précisément la propriété d'ordre qui<br/>
permet d'éliminer la moitié de l'arbre à<br/>
chaque comparaison. Sans cette propriété, on<br/>
retomberait sur un parcours linéaire de tous<br/>
les 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="100" format="html">
    <text><![CDATA[<p>`<code><br/>
def chercher(n, v):<br/>
    if n is None: return False<br/>
    if v == n.valeur: return True<br/>
    if v &lt; n.valeur:<br/>
        return chercher(n.gauche, v)<br/>
    return chercher(n.droit, v)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette fonction ne descend que dans <strong>un<br/>
seul</strong> sous-arbre selon la comparaison.<br/>
C'est ce qui donne la complexité<br/>
O(\log n) pour un arbre équilibré.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code><br/>
def chercher(n, v):<br/>
    return v == n.valeur<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette fonction ne descend pas dans<br/>
l'arbre. Elle ne renvoie un résultat<br/>
correct que si la valeur cherchée est<br/>
exactement à la racine.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code><br/>
def chercher(n, v):<br/>
    return True<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette fonction renvoie toujours True,<br/>
sans effectuer la moindre recherche.<br/>
Elle est manifestement incorrecte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code><br/>
def chercher(n, v):<br/>
    if n is None: return False<br/>
    if n.valeur == v: return True<br/>
    return chercher(n.gauche, v) or chercher(n.droit, v)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette fonction parcourt l'arbre entier<br/>
sans exploiter la propriété d'ordre. Sa<br/>
complexité est en O(n) et non en<br/>
O(\log n).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q11 : Arbres AVL</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un arbre AVL est un arbre binaire de<br/>
recherche auto-équilibré. Quelle contrainte<br/>
maintient-il pour rester équilibré ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'arbre AVL garantit, pour n nœuds, une<br/>
hauteur en O(\log n), et donc des<br/>
opérations en O(\log n). Le coût à payer<br/>
est l'effort de maintien (rotations) à<br/>
chaque insertion ou suppression.</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>Pour chaque nœud, les hauteurs des sous-arbres gauche et droit ne diffèrent jamais de plus de 1</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est la définition stricte d'un arbre<br/>
AVL. Lorsque cette propriété est violée<br/>
après une insertion, des <strong>rotations</strong><br/>
rétablissent l'équilibre. Les arbres AVL<br/>
ont été inventés par Adelson-Velsky et<br/>
Landis en 1962.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Tous les chemins de la racine aux feuilles ont la même longueur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette contrainte définirait un arbre<br/>
parfait, beaucoup plus rigide qu'un<br/>
arbre AVL.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Tous les sous-arbres doivent avoir la même taille</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La contrainte porte sur la <strong>hauteur</strong> des<br/>
sous-arbres, et non sur leur taille en<br/>
nombre de nœuds.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La racine doit toujours être la valeur médiane des valeurs présentes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Maintenir la médiane à la racine après<br/>
chaque opération serait beaucoup trop<br/>
coûteux. Ce n'est pas la stratégie<br/>
adoptée par les arbres AVL.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q12 : Arbres rouge-noir</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Les arbres rouge-noir sont une autre famille<br/>
d'arbres binaires de recherche<br/>
auto-équilibrés. Quelle est leur particularité<br/>
par rapport aux arbres AVL ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les arbres rouge-noir sont à la base de<br/>
nombreuses bibliothèques standard (std::map<br/>
en C++, TreeMap en Java). Ils ont été<br/>
inventés en 1972 par Bayer, puis<br/>
généralisés par Sedgewick.</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>Ils n'autorisent que les insertions, et pas les suppressions</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les arbres rouge-noir gèrent toutes les<br/>
opérations classiques : recherche,<br/>
insertion et suppression.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Ils sont parfaitement équilibrés</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Ils sont en réalité moins strictement<br/>
équilibrés que les arbres AVL, mais avec<br/>
un coût d'équilibrage moindre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Ils utilisent un tri par tas en interne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les arbres rouge-noir n'ont aucun rapport<br/>
avec les tas, qui constituent une<br/>
structure de données différente.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Ils tolèrent un déséquilibre légèrement supérieur (la hauteur reste majorée par 2 \log n), en échange d'opérations d'équilibrage moins fréquentes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Ce compromis est intéressant en pratique.<br/>
Les arbres AVL sont plus rapides en<br/>
recherche, parce que plus plats, mais<br/>
plus coûteux à maintenir. Les arbres<br/>
rouge-noir équilibrent ces deux aspects.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q13 : Insertion dans le pire cas</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans un arbre binaire de recherche <strong>non<br/>
équilibré</strong>, quelle séquence d'insertions<br/>
conduit au pire cas (forme dégénérée) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour éviter ce piège, deux solutions<br/>
classiques. On peut utiliser un arbre<br/>
auto-équilibré, ou bien mélanger les<br/>
insertions au préalable. C'est aussi la<br/>
motivation des arbres randomisés (treaps),<br/>
qui maintiennent l'équilibre grâce au<br/>
hasard.</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>Insérer les valeurs en commençant par la médiane</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Au contraire, insérer la médiane en<br/>
premier conduit à un arbre bien<br/>
équilibré.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Insérer une seule valeur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un arbre composé d'un seul nœud ne pose<br/>
évidemment aucun problème de<br/>
dégénérescence.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Insérer les valeurs dans un ordre aléatoire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Avec un ordre aléatoire, on tend vers une<br/>
bonne forme d'arbre, dont la hauteur est<br/>
en O(\log n) en espérance.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Insérer les valeurs déjà triées, par ordre croissant ou décroissant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>En insérant les valeurs 1, 2, 3, \ldots, n<br/>
dans l'ordre, chaque nouvelle valeur va à<br/>
droite de la précédente, ce qui crée un<br/>
peigne. La hauteur atteint alors n - 1<br/>
et toutes les opérations dégénèrent en<br/>
O(n).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q14 : Application du parcours infixe</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment obtenir efficacement les valeurs<br/>
<strong>triées</strong> d'un arbre binaire de recherche ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cette propriété permet d'utiliser un arbre<br/>
binaire de recherche pour réaliser un tri.<br/>
Avec n insertions en O(n \log n) amortis<br/>
et un parcours infixe en O(n), on obtient<br/>
un tri en O(n \log n), comparable à un<br/>
tri fusion ou à un tri rapide.</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>Trier les valeurs à chaque opération</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un arbre binaire de recherche maintient<br/>
déjà l'ordre par sa structure même. Il<br/>
serait redondant de retrier les valeurs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Ne renvoyer que les feuilles de l'arbre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On perdrait alors toutes les valeurs des<br/>
nœuds internes, ce qui est manifestement<br/>
incorrect.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Effectuer un parcours préfixe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le parcours préfixe ne donne pas les<br/>
valeurs triées en général. Seul le<br/>
parcours infixe possède cette propriété.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Effectuer un parcours infixe, qui visite naturellement les valeurs en ordre croissant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le parcours infixe en O(n) donne<br/>
directement les valeurs triées. On ne<br/>
peut pas faire mieux : il faut bien<br/>
visiter chaque élément au moins une<br/>
fois.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q15 : Code d'insertion récursive</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle fonction Python insère correctement la<br/>
valeur v dans un arbre binaire de<br/>
recherche, en renvoyant la nouvelle racine ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cette fonction est typique : elle parcourt<br/>
l'arbre depuis la racine en comparant les<br/>
valeurs, et crée un nouveau nœud à la place<br/>
vide trouvée. Sa complexité est en O(h),<br/>
où h est la hauteur de 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>`<code><br/>
def inserer(n, v):<br/>
    if n is None: return Noeud(v)<br/>
    if v &lt; n.valeur:<br/>
        n.gauche = inserer(n.gauche, v)<br/>
    else:<br/>
        n.droit = inserer(n.droit, v)<br/>
    return n<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Si l'arbre est vide, la fonction crée un<br/>
nouveau nœud. Sinon, elle descend<br/>
récursivement à gauche ou à droite selon<br/>
la comparaison, puis réaffecte le<br/>
sous-arbre modifié.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code><br/>
def inserer(n, v):<br/>
    return Noeud(v)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette fonction remplace l'arbre entier<br/>
par un seul nœud, perdant toutes les<br/>
valeurs précédemment insérées.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code><br/>
def inserer(n, v):<br/>
    n.valeur = v<br/>
    return n<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette fonction écrase la valeur de la<br/>
racine au lieu d'ajouter un nœud. Elle<br/>
ne construit pas un arbre binaire de<br/>
recherche.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code><br/>
def inserer(n, v):<br/>
    n.gauche = Noeud(v)<br/>
    return n<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette fonction insère toujours à gauche,<br/>
sans tenir compte de la valeur de v.<br/>
Elle viole donc systématiquement la<br/>
propriété d'ordre.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q16 : Construire un arbre équilibré</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour construire un arbre binaire de recherche<br/>
équilibré à partir d'un tableau trié, quelle<br/>
stratégie est la plus simple ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cet algorithme est en O(n). Il est utile<br/>
pour reconstruire un arbre équilibré à<br/>
partir d'une séquence triée, par exemple<br/>
lors d'une migration de données.</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>Insérer les éléments dans un ordre aléatoire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette approche donne un arbre presque<br/>
équilibré en moyenne, mais sans aucune<br/>
garantie absolue.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Insérer les éléments dans l'ordre du tableau</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette stratégie produit précisément un<br/>
peigne dégénéré, puisque les valeurs<br/>
sont déjà triées.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Prendre l'élément du milieu comme racine, puis construire récursivement le sous-arbre gauche à partir de la moitié inférieure et le sous-arbre droit à partir de la moitié supérieure</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est l'algorithme classique. La moitié<br/>
de gauche devient le sous-arbre gauche,<br/>
construit récursivement par la même<br/>
méthode, et de même pour la moitié de<br/>
droite. L'arbre obtenu est parfaitement<br/>
équilibré, de hauteur O(\log n).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Insérer les éléments du dernier au premier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette stratégie produit un peigne<br/>
dégénéré dans l'autre sens, ce qui n'est<br/>
pas plus satisfaisant.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q17 : Échec de la recherche</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Lorsque la recherche d'une valeur <strong>absente</strong><br/>
se termine dans un arbre binaire de recherche,<br/>
à quel endroit s'arrête-t-on ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>C'est ce comportement qui permet la recherche<br/>
en O(h) : on ne descend que dans une seule<br/>
branche, ce qui prend au plus \log n<br/>
étapes pour un arbre é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>À la racine de l'arbre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On s'arrête en général à un endroit plus<br/>
profond dans l'arbre, lorsque la branche<br/>
recherchée est vide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La fonction lève une exception</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On renvoie typiquement la valeur False<br/>
ou None, sans lever d'exception<br/>
(sauf si on adopte volontairement cette<br/>
convention).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>À un sous-arbre vide (None), preuve que la valeur n'est pas présente dans l'arbre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>À chaque étape, on choisit le sous-arbre<br/>
gauche ou le sous-arbre droit. Si la<br/>
valeur n'est jamais égale au nœud<br/>
courant et que l'on atteint un<br/>
sous-arbre vide, c'est qu'elle est<br/>
absente.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À une feuille, peu importe sa valeur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>On ne s'arrête pas systématiquement à<br/>
une feuille. On peut s'arrêter à un<br/>
sous-arbre vide pendant à un nœud<br/>
interne.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q18 : Vérifier la propriété d'ordre</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour vérifier qu'un arbre binaire respecte la<br/>
propriété d'arbre binaire de recherche, il<br/>
<strong>ne suffit pas</strong> de vérifier localement à<br/>
chaque nœud que :</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'algorithme correct consiste à transmettre<br/>
récursivement les bornes (min, max) que<br/>
la valeur de chaque nœud doit respecter. La<br/>
racine accepte toutes les valeurs, le<br/>
sous-arbre gauche reçoit l'intervalle<br/>
(\min, \text{valeur}) et le sous-arbre<br/>
droit reçoit l'intervalle<br/>
(\text{valeur}, \max).</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>Les feuilles se trouvent toutes au même niveau</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Aucune contrainte de niveau n'est<br/>
imposée dans un arbre binaire de<br/>
recherche.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La hauteur des sous-arbres est équilibrée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette propriété correspond à<br/>
l'équilibre, et non à la propriété<br/>
d'ordre qui définit un arbre binaire de<br/>
recherche.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>L'enfant gauche est plus petit et l'enfant droit est plus grand. Il faut aussi vérifier que toutes les valeurs du sous-arbre gauche sont inférieures (et symétriquement pour le sous-arbre droit)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est un piège classique. Vérifier<br/>
uniquement les enfants directs ne<br/>
suffit pas. La propriété d'arbre<br/>
binaire de recherche demande que<br/>
<strong>tout</strong> le sous-arbre gauche soit<br/>
inférieur à la valeur du nœud, et pas<br/>
seulement la racine de ce sous-arbre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La valeur du nœud est la moyenne de celles de ses enfants</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette propriété correspond à un autre<br/>
type d'arbre, mais elle n'a aucun<br/>
rapport avec la définition d'un arbre<br/>
binaire de recherche.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q19 : Comparaison avec une table de hachage</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comparé à une <strong>table de hachage</strong>, quel est<br/>
l'<strong>avantage</strong> d'un arbre binaire de<br/>
recherche ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le choix dépend du besoin. Pour des accès<br/>
par clé sans contrainte d'ordre, la table<br/>
de hachage est préférable. Pour maintenir<br/>
les valeurs en ordre ou répondre à des<br/>
requêtes par intervalle, l'arbre binaire de<br/>
recherche est mieux adapté.</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 maintient les éléments dans l'ordre, ce qui permet de répondre à des requêtes par intervalle ou de retrouver le voisin le plus proche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un arbre binaire de recherche permet de<br/>
répondre à des questions comme « tous<br/>
les éléments entre a et b » ou<br/>
« le plus petit élément supérieur ou égal<br/>
à v » en O(\log n). Une table de<br/>
hachage ne le permet pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il consomme moins de mémoire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation n'est pas<br/>
systématiquement vraie. La consommation<br/>
mémoire dépend de l'implémentation des<br/>
deux structures.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il est plus simple à implémenter</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Au contraire, un arbre binaire de<br/>
recherche auto-équilibré est en<br/>
général plus complexe à implémenter<br/>
qu'une table de hachage.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La recherche y est plus rapide</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est l'inverse. Une table de hachage<br/>
a une recherche en O(1) amorti, ce<br/>
qui est plus rapide que le O(\log n)<br/>
d'un arbre binaire de recherche.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q20 : Lecture d'un arbre</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On insère successivement les valeurs 5,<br/>
2, 8, 1, 3 dans un arbre binaire de<br/>
recherche initialement vide. Quel est le<br/>
résultat de son parcours infixe ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cet exemple illustre parfaitement la<br/>
propriété d'ordre. Dessiner l'arbre est<br/>
souvent utile pour visualiser et vérifier<br/>
les différents parcours.</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>8, 5, 3, 2, 1 (ordre décroissant)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette séquence correspond au parcours<br/>
infixe inversé, et non au parcours<br/>
infixe standard.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>1, 2, 3, 5, 8 (ordre croissant)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le parcours infixe donne toujours les<br/>
valeurs en ordre croissant. On peut le<br/>
vérifier en construisant l'arbre :<br/>
racine 5, sous-arbre gauche enraciné<br/>
en 2 (avec 1 et 3), sous-arbre<br/>
droit réduit à 8. Le parcours infixe<br/>
donne bien 1, 2, 3, 5, 8.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>5, 2, 1, 3, 8 (parcours préfixe)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette séquence correspond au parcours<br/>
<strong>préfixe</strong> (racine, gauche, droite),<br/>
et non au parcours infixe.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>5, 2, 8, 1, 3 (ordre d'insertion)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le parcours infixe d'un arbre binaire<br/>
de recherche donne les valeurs triées,<br/>
et non l'ordre d'insertion d'origine.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q21 : Suppression d'un nœud à deux enfants</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour supprimer un nœud à <strong>deux enfants</strong> dans<br/>
un arbre binaire de recherche, par quoi le<br/>
remplace-t-on ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le successeur infixe se trouve en<br/>
descendant une fois à droite, puis tout à<br/>
gauche. Cette opération s'effectue en<br/>
O(h) étapes au pire, où h est la<br/>
hauteur de 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="0" format="html">
    <text><![CDATA[<p>Par le sous-arbre gauche complet</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Déplacer un sous-arbre entier ne<br/>
conserverait pas la propriété d'ordre<br/>
de l'arbre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Par la racine de l'arbre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette opération briserait toute la<br/>
structure de l'arbre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Par une feuille choisie au hasard</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Choisir une feuille au hasard violerait<br/>
la propriété d'ordre de l'arbre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Par son successeur infixe (le plus petit nœud du sous-arbre droit) ou par son prédécesseur infixe (le plus grand du sous-arbre gauche)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Ce nœud est le plus proche du nœud<br/>
supprimé dans l'ordre des valeurs. Il a<br/>
forcément au plus un enfant (sinon, un<br/>
nœud encore plus à gauche existerait),<br/>
ce qui rend sa suppression simple. On<br/>
copie sa valeur dans le nœud à<br/>
supprimer, puis on supprime ce<br/>
successeur.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q22 : Hauteur attendue</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour un arbre binaire de recherche construit<br/>
en insérant n valeurs <strong>dans un ordre<br/>
aléatoire</strong>, quelle est la hauteur attendue ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Ce résultat justifie l'utilisation<br/>
d'arbres binaires de recherche non<br/>
auto-équilibrés lorsque l'on contrôle<br/>
l'ordre d'insertion (par exemple en<br/>
mélangeant les données au préalable). Les<br/>
structures auto-équilibrées garantissent<br/>
une complexité en O(\log n) même dans<br/>
le pire cas.</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)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette croissance ne correspond pas au<br/>
comportement asymptotique de la<br/>
hauteur d'un arbre binaire de<br/>
recherche.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Θ(n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette hauteur correspond au pire cas<br/>
(insertion dans un ordre déjà trié) et<br/>
non au cas moyen. Avec un ordre<br/>
aléatoire, le résultat est bien<br/>
meilleur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>\Theta(\log n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est un résultat classique. En<br/>
espérance (sur l'ordre aléatoire<br/>
d'insertion), la hauteur est en<br/>
\Theta(\log n). Toutes les opérations<br/>
ont alors une complexité moyenne en<br/>
O(\log n), sans qu'aucun équilibrage<br/>
explicite soit nécessaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Θ(1)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La hauteur d'un arbre croît<br/>
nécessairement avec le nombre de<br/>
valeurs n. Elle ne peut pas rester<br/>
constante.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q23 : Tri par arbre binaire de recherche</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Le tri par arbre binaire de recherche, qui<br/>
consiste à insérer n valeurs dans un arbre<br/>
puis à effectuer un parcours infixe, a une<br/>
complexité de :</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cet algorithme illustre un compromis : il<br/>
est avantageux pour des données aléatoires,<br/>
mais fragile dans le pire cas. C'est<br/>
pourquoi on préfère en pratique le tri<br/>
fusion (toujours en O(n \log n)<br/>
garanti) ou le tri rapide (souvent en<br/>
O(n \log n) avec un bon choix de<br/>
pivot).</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(n!)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette complexité factorielle est<br/>
encore plus excessive et ne correspond<br/>
à aucun algorithme de tri raisonnable.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>O(n \log n) en moyenne (avec un ordre aléatoire), mais O(n²) dans le pire cas (ordre déjà trié)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Chaque insertion est en O(\log n) en<br/>
moyenne, ce qui donne O(n \log n)<br/>
pour les n insertions, auxquelles<br/>
s'ajoute O(n) pour le parcours<br/>
infixe. Total : O(n \log n) en<br/>
moyenne. Mais avec un ordre<br/>
d'insertion défavorable, la hauteur<br/>
explose et la complexité atteint<br/>
O(n²).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Insérer n valeurs dans une structure<br/>
ordonnée ne peut pas se faire en<br/>
O(n). Tout tri par comparaisons est<br/>
au moins en \Omega(n \log n).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(2ⁿ)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette complexité exponentielle n'a<br/>
aucune raison d'apparaître dans un<br/>
tri.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q24 : Successeur d'un nœud</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Étant donné un nœud n dans un arbre binaire<br/>
de recherche, comment trouver son<br/>
<strong>successeur infixe</strong>, c'est-à-dire la valeur<br/>
immédiatement supérieure ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cette logique permet d'implémenter un<br/>
<strong>itérateur</strong> sur un arbre binaire de<br/>
recherche, qui produit les valeurs en<br/>
ordre croissant sans stockage<br/>
supplémentaire (à part une pile implicite<br/>
pour remonter dans 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="0" format="html">
    <text><![CDATA[<p>La racine de l'arbre est toujours le successeur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette description est trop simpliste<br/>
et incorrecte. Le successeur d'un<br/>
nœud n'est pas en général la racine.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>En descendant toujours à gauche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette stratégie n'est pas systématique.<br/>
Le successeur peut très bien se trouver<br/>
ailleurs dans l'arbre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le successeur est choisi au hasard parmi les autres nœuds</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La détermination du successeur est<br/>
strictement déterministe : aucun<br/>
hasard n'intervient.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Si le nœud n a un sous-arbre droit, son successeur est le nœud le plus à gauche de ce sous-arbre. Sinon, c'est le premier ancêtre dont n se trouve dans le sous-arbre gauche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est la définition correcte. En<br/>
parcourant ainsi, on visite l'arbre<br/>
dans l'ordre infixe sans utiliser la<br/>
récursion, ce qui est très pratique<br/>
pour implémenter un itérateur.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q25 : Quand utiliser un arbre binaire de recherche ?</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Lequel des cas suivants justifie l'usage<br/>
d'un arbre binaire de recherche<br/>
auto-équilibré plutôt qu'une autre structure<br/>
?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour résumer : on utilise un arbre binaire<br/>
de recherche pour des accès <strong>dynamiques</strong><br/>
avec maintien d'un <strong>ordre</strong> sur les<br/>
valeurs. Pour des données statiques ou<br/>
sans besoin d'ordre, des structures plus<br/>
simples suffisent.</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>Implémenter un dictionnaire dont les clés sont triées dynamiquement, avec des recherches par intervalle fréquentes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est exactement le cas d'usage des<br/>
arbres binaires de recherche<br/>
auto-équilibrés. Cette structure<br/>
permet, en O(\log n), de répondre à<br/>
des requêtes comme « les clés entre<br/>
a et b » ou « la plus petite clé<br/>
supérieure ou égale à v ».</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Calculer la somme des éléments d'une grande liste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un parcours linéaire en O(n) suffit<br/>
pour cette tâche. Aucune structure<br/>
d'arbre n'apporterait de gain.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Stocker une liste fixe de noms à afficher</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pour des données statiques, une liste<br/>
triée stockée dans un tableau suffit.<br/>
Aucun arbre binaire de recherche<br/>
n'est nécessaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Trier 1 000 entiers une seule fois</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pour ce besoin, les algorithmes de tri<br/>
classiques (tri fusion, tri rapide)<br/>
sont plus simples et tout aussi<br/>
efficaces.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q26 : Trace d'insertions successives</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On part d'un arbre binaire de recherche<br/>
vide. On y insère successivement les valeurs<br/>
10, 5, 15, 3, 7, 12. À quoi ressemble la<br/>
structure obtenue ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cet arbre obtenu (6 nœuds, hauteur 2) est<br/>
bien équilibré, ce qui n'est pas un hasard :<br/>
la séquence d'insertion alterne intelligemment<br/>
entre les côtés. Avec une mauvaise séquence<br/>
(1, 2, 3, 4, 5, 6), on aurait obtenu un<br/>
peigne de hauteur 5.</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>Tous les nœuds sont des feuilles d'une<br/>
racine vide</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un arbre binaire de recherche<br/>
n'a pas de « racine vide ». La première<br/>
valeur insérée devient la racine, et les<br/>
suivantes sont placées comme descendants.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Tous les nœuds sur une branche droite,<br/>
formant un peigne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on aurait un peigne uniquement<br/>
si les valeurs étaient insérées dans<br/>
l'ordre croissant ou décroissant. Ici,<br/>
l'ordre est plus équilibré.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Racine 5 ; tous les autres nœuds<br/>
répartis selon leur valeur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la racine est toujours la<br/>
<strong>première</strong> valeur insérée, ici 10,<br/>
pas 5.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Racine 10 ; sous-arbre gauche : 5 avec<br/>
3 à gauche et 7 à droite ; sous-arbre<br/>
droit : 15 avec 12 à gauche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : à chaque insertion, on<br/>
compare avec la racine pour choisir le<br/>
sous-arbre. 10 devient racine. 5 &lt; 10<br/>
va à gauche. 15 &gt; 10 va à droite. 3 &lt; 10<br/>
puis 3 &lt; 5 va à gauche de 5. 7 &lt; 10<br/>
puis 7 &gt; 5 va à droite de 5. 12 &gt; 10<br/>
puis 12 &lt; 15 va à gauche de 15.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q27 : Code de vérification de la propriété</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle fonction Python vérifie correctement<br/>
qu'un arbre binaire respecte la propriété<br/>
d'arbre binaire de recherche (en utilisant<br/>
des bornes minimum et maximum) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le piège pédagogique de cette question est<br/>
la première option, qui semble naturelle<br/>
mais rate les violations à distance. C'est<br/>
pour cela que la transmission de bornes par<br/>
paramètre est essentielle : elle propage la<br/>
contrainte d'ordre tout au long de la<br/>
descente 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>`<code><br/>
def est_abr(n):<br/>
    if n is None:<br/>
        return True<br/>
    if n.gauche and n.gauche.valeur &gt;= n.valeur:<br/>
        return False<br/>
    if n.droit and n.droit.valeur &lt;= n.valeur:<br/>
        return False<br/>
    return est_abr(n.gauche) and est_abr(n.droit)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur classique : on ne vérifie que la<br/>
relation parent/enfant direct. Cela rate<br/>
des cas comme racine 10, gauche 5,<br/>
droite-gauche-droite 20 (qui est dans<br/>
le sous-arbre gauche de 10 mais<br/>
supérieure à 10). L'arbre serait<br/>
déclaré valide à tort.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code><br/>
def est_abr(n):<br/>
    return n is None<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : cette fonction renvoie True<br/>
uniquement pour l'arbre vide, et False<br/>
pour tout arbre non vide, ce qui est<br/>
manifestement faux.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>`<code><br/>
def est_abr(n, mini=float('-inf'), maxi=float('inf')):<br/>
    if n is None:<br/>
        return True<br/>
    if not (mini &lt; n.valeur &lt; maxi):<br/>
        return False<br/>
    return est_abr(n.gauche, mini, n.valeur) and est_abr(n.droit, n.valeur, maxi)<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on transmet à chaque<br/>
appel récursif les bornes que la valeur<br/>
du sous-arbre doit respecter. À gauche,<br/>
on resserre la borne supérieure ; à<br/>
droite, la borne inférieure. C'est le<br/>
schéma correct qui détecte aussi les<br/>
violations « profondes » (par exemple,<br/>
un nœud lointain qui violerait l'ordre).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code><br/>
def est_abr(n):<br/>
    if n is None:<br/>
        return True<br/>
    return parcours_infixe(n) == sorted(parcours_infixe(n))<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette approche est correcte mais<br/>
inefficace : elle nécessite un parcours<br/>
complet, un tri en O(n \log n) et une<br/>
comparaison. La version récursive avec<br/>
bornes est en O(n) et plus élégante.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q28 : Minimum et maximum dans un ABR</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment trouver respectivement le <strong>minimum</strong><br/>
et le <strong>maximum</strong> d'un arbre binaire de<br/>
recherche non vide ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cette propriété est exploitée dans la<br/>
suppression d'un nœud à deux enfants : on<br/>
remplace le nœud par son <strong>successeur<br/>
infixe</strong> (le minimum de son sous-arbre droit)<br/>
ou son <strong>prédécesseur infixe</strong> (le maximum de<br/>
son sous-arbre gauche), tous deux trouvables<br/>
en O(h).</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 minimum est toujours la racine, le<br/>
maximum est toujours une feuille</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la racine est la <strong>première<br/>
valeur insérée</strong>, pas le minimum. Le<br/>
minimum est dans le sous-arbre le plus à<br/>
gauche. Quant au maximum, il peut être<br/>
n'importe où à droite, pas forcément une<br/>
feuille.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>On parcourt tout l'arbre et on retient les<br/>
valeurs minimale et maximale au fur et à<br/>
mesure</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette méthode fonctionne (en O(n)) mais<br/>
ignore la propriété d'ordre. Avec<br/>
l'arbre binaire de recherche, on peut<br/>
faire bien mieux en descendant<br/>
directement à gauche ou à droite, en<br/>
O(h).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Le minimum se trouve en descendant toujours<br/>
à gauche depuis la racine ; le maximum<br/>
en descendant toujours à droite. Les<br/>
deux opérations sont en O(h) où h est<br/>
la hauteur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : par la propriété d'ordre,<br/>
tous les nœuds plus petits qu'un nœud<br/>
donné sont à sa gauche. En descendant<br/>
systématiquement à gauche jusqu'à<br/>
atteindre une feuille (sans enfant<br/>
gauche), on trouve la plus petite valeur.<br/>
Symétriquement à droite pour le maximum.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le minimum et le maximum sont les deux<br/>
enfants de la racine</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : seul l'enfant gauche <strong>direct</strong><br/>
de la racine peut être plus petit qu'elle,<br/>
pas un éventuel descendant plus profond.<br/>
Et symétriquement à droite. La descente<br/>
jusqu'au bout est nécessaire.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
