<?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 exactement 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>Sous-arbre gauche inférieur, sous-arbre droit supérieur</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 toujours la plus grande valeur de l'arbre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Dans un arbre binaire de recherche, la racine n'a aucune raison de porter la plus grande valeur : les valeurs plus grandes qu'elle se trouvent dans son sous-arbre droit, et la racine peut ê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^2)$</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 cas</strong>, sans contrainte d'équilibrage ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Ce phénomène de dégénérescence explique pourquoi on cherche à garder l'arbre équilibré : la recherche dans un arbre binaire de recherche équilibré est de coût logarithmique, 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>$O(\sqrt{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^2)$, soit quadratique</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)$, arbre dégénéré en peigne</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 en comparant, puis on insère comme nouvelle feuille</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 : Nœuds visités lors d'une recherche</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans un arbre binaire de recherche, la racine porte $50$ ; ses enfants sont $30$ à gauche et $70$ à droite ; $30$ a pour enfants $20$ et $40$, et $70$ a pour enfants $60$ et $80$. On recherche la clé $60$. Quels nœuds sont visités, dans l'ordre ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La recherche d'une clé part de la racine et, à chaque nœud, compare la clé cherchée à celle du nœud : plus petite, on descend à gauche ; plus grande, à droite. On visite ainsi au plus un nœud par niveau 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>$50$, $30$, $70$, $60$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : tu visites l'arbre niveau par niveau. La recherche compare $60$ à $50$ et part aussitôt à droite : le sous-arbre gauche, qui ne contient que des clés plus petites que $50$, n'est jamais visité.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>$50$, $70$, $60$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : $60 &gt; 50$, on descend à droite vers $70$ ; $60 &lt; 70$, on descend à gauche et l'on trouve $60$. Trois nœuds suffisent.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$20$, $30$, $40$, $50$, $60$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : tu suis le parcours infixe jusqu'à trouver la clé. La recherche part de la racine et, grâce à la propriété d'ordre, ne descend que d'un côté à chaque étape.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$50$, $30$, $20$, $40$, $70$, $60$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : tu suis le parcours préfixe jusqu'à trouver la clé. Comparer $60$ à la racine suffit pour savoir qu'il est inutile d'explorer le sous-arbre gauche.</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>Insertion et suppression en $O(\log n)$ au lieu de $O(n)$</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$, $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 la plus petite de toutes et<br/>
finit en feuille tout à gauche. La racine est toujours<br/>
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 insérée en dernier. Elle<br/>
finit 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, un arbre binaire de recherche maintenu équilibré permet d'ajouter et de chercher rapidement des éléments tout en les gardant ordonnés : le parcours infixe les restitue triés à tout moment.</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 un ensemble trié dynamique avec ajouts fréquents</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 de tous les éléments d'une liste donnée</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 <code>v</code> 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[<pre><code>def chercher(n, v):
    if n is None: return False
    if v == n.valeur: return True
    if v &lt; n.valeur:
        return chercher(n.gauche, v)
    return chercher(n.droit, v)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette fonction ne descend que dans <strong>un 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[<pre><code>def chercher(n, v):
    if v == n.valeur: return True
    if v &lt; n.valeur:
        return chercher(n.gauche, v)
    return chercher(n.droit, v)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur classique : le cas de base de l'arbre<br/>
vide manque. Dès que <code>v</code> est absente, la<br/>
descente atteint un sous-arbre <code>None</code> et<br/>
<code>n.valeur</code> lève une <code>AttributeError</code> au lieu<br/>
de renvoyer <code>False</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def chercher(n, v):
    if n is None: return False
    if v == n.valeur: return True
    if v &lt; n.valeur:
        return chercher(n.droit, v)
    return chercher(n.gauche, v)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les directions sont inversées. Dans<br/>
un arbre binaire de recherche, les valeurs<br/>
plus petites que <code>n.valeur</code> sont à <strong>gauche</strong>.<br/>
Cette fonction ne trouve que la valeur de la<br/>
racine.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def chercher(n, v):
    if n is None: return False
    if n.valeur == v: return True
    return chercher(n.gauche, v) or chercher(n.droit, v)</code></pre>]]></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 — Q13 : Insertion dans le pire cas</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans un arbre binaire de recherche <strong>non é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, on peut mélanger les valeurs avant de les insérer, ou choisir un ordre d'insertion qui place en premier la médiane, puis les médianes de chaque moitié.</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</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/>
Si l'arbre reste équilibré, les $n$ insertions<br/>
coûtent $O(n \log n)$ au total ; avec le<br/>
parcours infixe en $O(n)$, on obtient un tri<br/>
en $O(n \log n)$, comparable au tri fusion.</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 plutôt un simple 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 (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 <code>v</code> 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[<pre><code>def inserer(n, v):
    if n is None: return Noeud(v)
    if v &lt; n.valeur:
        n.gauche = inserer(n.gauche, v)
    else:
        n.droit = inserer(n.droit, v)
    return n</code></pre>]]></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[<pre><code>def inserer(n, v):
    if n is None:
        n = Noeud(v)
    elif v &lt; n.valeur:
        inserer(n.gauche, v)
    else:
        inserer(n.droit, v)
    return n</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur classique : les appels récursifs ne<br/>
réaffectent pas leur résultat. Le nœud créé<br/>
au cas de base est perdu (l'affectation<br/>
locale <code>n = Noeud(v)</code> ne modifie pas l'arbre<br/>
du parent). Il faut écrire<br/>
<code>n.gauche = inserer(n.gauche, v)</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def inserer(n, v):
    if n is None: return Noeud(v)
    if v &lt; n.valeur:
        n.gauche = inserer(n.gauche, v)
    else:
        n.droit = inserer(n.droit, v)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur classique : le <code>return n</code> final manque.<br/>
Pour tout arbre non vide, la fonction renvoie<br/>
<code>None</code>, que le parent affecte à <code>n.gauche</code> ou<br/>
<code>n.droit</code> : le sous-arbre existant est détruit<br/>
à chaque insertion.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def inserer(n, v):
    if v &lt; n.valeur:
        n.gauche = Noeud(v)
    else:
        n.droit = Noeud(v)
    return n</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la fonction ne descend pas dans<br/>
l'arbre. Elle accroche le nouveau nœud<br/>
directement sous la racine, en écrasant le<br/>
sous-arbre qui s'y trouvait déjà, et elle<br/>
échoue sur un arbre vide.</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 directement dans l'ordre exact 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>Le milieu comme racine, puis récursivement des deux côtés</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 <code>False</code><br/>
ou <code>None</code>, 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 (<code>None</code>)</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 quelconque, 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 (<code>min</code>, <code>max</code>) 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, le droit plus grand</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 exactement 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 — Q20 : Lecture d'un arbre</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On insère successivement les valeurs $5$, $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é en $2$ (avec $1$ et $3$), sous-arbre 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 : Du parcours préfixe au parcours suffixe</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Le parcours préfixe d'un arbre binaire de recherche donne les clés $8$, $3$, $1$, $6$, $10$, $14$. Quel est le parcours suffixe de cet arbre ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le parcours préfixe commence par la racine, ici $8$. En insérant les clés dans l'ordre du parcours préfixe, on reconstruit le même arbre : $3$ à gauche de $8$, $1$ et $6$ sous $3$, $10$ à droite de $8$, puis $14$ à droite de $10$. Il ne reste qu'à le parcourir en ordre suffixe.</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>$1$, $3$, $6$, $8$, $10$, $14$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le parcours infixe, qui donne toujours les clés triées dans un arbre binaire de recherche. Le parcours suffixe traite chaque nœud après ses deux sous-arbres.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$14$, $10$, $6$, $1$, $3$, $8$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le parcours suffixe n'est pas le préfixe lu à l'envers. Il visite d'abord le sous-arbre gauche, puis le droit, puis le nœud.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$1$, $6$, $3$, $10$, $14$, $8$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : $14$ est l'enfant droit de $10$. En suffixe, un nœud vient après ses enfants : $14$ doit donc précéder $10$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>$1$, $6$, $3$, $14$, $10$, $8$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la racine est $8$ ; à gauche, $3$ a pour enfants $1$ et $6$ ; à droite, $10$ a pour enfant droit $14$. Le suffixe donne $1$, $6$, $3$, puis $14$, $10$, et enfin $8$.</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 est avantageux pour des données aléatoires, mais fragile dans le pire cas. C'est pourquoi on préfère souvent le tri fusion, dont le coût reste en $O(n \log n)$ dans tous les 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>$O(n!)$, à cause des $n!$ ordres d'insertion possibles</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le nombre d'ordres d'insertion possibles<br/>
n'intervient pas : on n'en suit qu'un<br/>
seul, celui des données. Une complexité<br/>
factorielle ne correspond à aucun<br/>
algorithme de tri raisonnable.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>$O(n \log n)$ en moyenne, $O(n^2)$ au pire</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^2)$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$O(n)$ quel que soit l'ordre d'insertion</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Chaque insertion descend dans l'arbre en faisant une comparaison par niveau. Même dans un arbre équilibré, de hauteur proche de $\log_2 n$, les $n$ insertions demandent de l'ordre de $n \log_2 n$ comparaisons, et bien davantage si l'arbre dégénère.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$O(2^n)$, car chaque nœud possède deux sous-arbres</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Chaque insertion ne suit qu'un seul<br/>
chemin de la racine vers une feuille ;<br/>
les deux sous-arbres d'un nœud ne sont<br/>
jamais explorés tous les deux. Une<br/>
complexité exponentielle n'a aucune<br/>
raison d'apparaître dans un tri.</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 d'un arbre binaire de recherche plutôt qu'une autre structure ?</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>Un dictionnaire à clés triées dynamiquement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est exactement le cas d'usage d'un arbre binaire de recherche : maintenu équilibré, il permet d'ajouter ou de chercher une clé en $O(\log n)$ tout en gardant les clés ordonnées, que le parcours infixe restitue triées.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Calculer la somme de tous les é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, un algorithme de tri classique, comme le tri fusion, est plus simple et tout aussi efficace.</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$, à gauche $5$ (avec $3$ et $7$), à droite $15$ (avec $12$)</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 version qui ne compare chaque nœud qu'à ses<br/>
enfants directs : elle semble naturelle mais<br/>
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[<pre><code>def est_abr(n):
    if n is None:
        return True
    if n.gauche and n.gauche.valeur &gt;= n.valeur:
        return False
    if n.droit and n.droit.valeur &lt;= n.valeur:
        return False
    return est_abr(n.gauche) and est_abr(n.droit)</code></pre>]]></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[<pre><code>def est_abr(n, mini=float('-inf'), maxi=float('inf')):
    if n is None:
        return True
    if not (mini &lt; n.valeur &lt; maxi):
        return False
    return est_abr(n.gauche, mini, maxi) and est_abr(n.droit, mini, maxi)</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les bornes sont transmises telles<br/>
quelles aux deux sous-arbres, sans jamais<br/>
être resserrées. Avec les bornes infinies<br/>
initiales, la condition<br/>
<code>mini &lt; n.valeur &lt; maxi</code> reste toujours<br/>
vraie : la fonction renvoie <code>True</code> pour<br/>
n'importe quel arbre binaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>def est_abr(n, mini=float('-inf'), maxi=float('inf')):
    if n is None:
        return True
    if not (mini &lt; n.valeur &lt; maxi):
        return False
    return est_abr(n.gauche, mini, n.valeur) and est_abr(n.droit, n.valeur, maxi)</code></pre>]]></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[<pre><code>def est_abr(n):
    if n is None:
        return True
    return parcours_prefixe(n) == sorted(parcours_prefixe(n))</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : seul le parcours <strong>infixe</strong> d'un<br/>
ABR est trié. Le parcours préfixe commence<br/>
par la racine, donc un ABR ordinaire<br/>
(racine $10$, fils gauche $5$) est déclaré<br/>
invalide, alors qu'une simple chaîne de<br/>
fils droits est acceptée. Même avec le<br/>
parcours infixe, cette approche coûterait<br/>
un tri en $O(n \log n)$, contre $O(n)$<br/>
pour la version à bornes.</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é rejoint le parcours infixe : dans un arbre binaire de recherche, le minimum est la première clé affichée par ce parcours et le maximum la dernière.</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 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 tout à gauche, le maximum tout à droite, en $O(h)$</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>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q29 : Le nombre de niveaux minimal pour ranger des clés</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Combien de niveaux, au minimum, un arbre binaire de recherche<br/>
doit-il avoir pour contenir $15$ clés ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Avec $k$ niveaux pleins, un arbre contient $2^k - 1$ clés : le<br/>
nombre minimal de niveaux croît comme $\log_2 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>$4$, en remplissant chaque niveau</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : $4$ niveaux pleins contiennent<br/>
$2^{4} - 1 = 15$ nœuds, juste ce qu'il faut. C'est la<br/>
forme équilibrée, qui donne une recherche en $\log_2 n$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$7$, la moitié des clés environ</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : chaque niveau peut contenir le double du précédent,<br/>
les niveaux sont bien moins nombreux.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$5$, un niveau de plus pour la racine</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la racine occupe le premier niveau, déjà compté.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$15$, une clé à chaque niveau</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le pire cas, l'arbre filiforme, pas le minimum.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q30 : Le coût total d'insertions dans l'ordre croissant</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On insère les clés $1, 2, \ldots, 10$ dans cet ordre dans un<br/>
arbre binaire de recherche vide. Chaque insertion compare la<br/>
nouvelle clé à chaque nœud du chemin parcouru. Combien de<br/>
comparaisons en tout ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les clés triées sont le pire ordre d'insertion : l'arbre dégénère<br/>
en liste et le coût cumulé devient quadratique.</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>$45$, soit $0 + 1 + \cdots + 9$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : l'arbre devient une chaîne ; la $k$-ième clé<br/>
descend le long des $k - 1$ nœuds déjà présents. Le total est<br/>
$10 \times 9 / 2 = 45$, de l'ordre de $n^2$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$10$, une seule par insertion</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : chaque insertion coûte autant de comparaisons que de<br/>
nœuds sur son chemin, pas une seule.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$100$, soit $n$ par insertion</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la $k$-ième insertion ne compare qu'avec $k - 1$<br/>
nœuds, pas $n$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$9$, une par nœud déjà présent</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : $9$ est le coût de la dernière insertion seulement.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q31 : L'intérêt de rééquilibrer un arbre</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Certaines bibliothèques rééquilibrent l'arbre binaire de recherche<br/>
après chaque insertion, au prix d'un travail supplémentaire.<br/>
Qu'y gagne-t-on ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les coûts logarithmiques d'un arbre binaire de recherche supposent<br/>
un arbre équilibré ; le garantir a un prix à chaque insertion.</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>Une hauteur en $\log n$, quel que soit l'ordre des insertions</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : sans rééquilibrage, des clés insérées dans<br/>
l'ordre dégradent l'arbre en liste ; le rééquilibrage maintient<br/>
toutes les opérations en $\log n$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La possibilité de ranger des clés en double sans conflit</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les doublons relèvent d'une convention, pas de<br/>
l'équilibre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un parcours infixe plus rapide, en $\log n$ au lieu de $n$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le parcours infixe visite tous les nœuds, il reste en<br/>
$n$ quelle que soit la forme.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une mémoire réduite, les nœuds étant rangés plus serrés</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le nombre de nœuds ne change pas, la mémoire non<br/>
plus.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q32 : L'ordre d'insertion et la forme de l'arbre</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Deux programmes insèrent les mêmes clés dans un arbre binaire de<br/>
recherche vide, mais dans des ordres différents. Obtiennent-ils le<br/>
même arbre ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un arbre binaire de recherche garde la trace de l'ordre dans lequel<br/>
il a été construit ; seul le parcours infixe en est indépendant.</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>Pas forcément, l'ordre d'insertion détermine la forme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la première clé devient la racine, et chaque<br/>
suivante se place sous les précédentes. Les clés $1, 2, 3$<br/>
donnent une chaîne ; $2, 1, 3$ donnent un arbre équilibré.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Oui, un ensemble de clés donne toujours le même arbre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : seul le parcours infixe est le même ; la forme dépend<br/>
de l'ordre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Non, jamais, deux ordres donnant deux arbres distincts</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : deux ordres différents peuvent donner le même arbre,<br/>
par exemple $2, 1, 3$ et $2, 3, 1$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Oui, à condition que les clés soient des entiers</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le type des clés ne change rien.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q33 : Le coût de la recherche du minimum</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour trouver la plus petite clé d'un arbre binaire de recherche,<br/>
on descend à gauche tant que possible. Quel est le coût de cette<br/>
recherche ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le coût des opérations d'un arbre binaire de recherche se lit sur<br/>
sa hauteur, et la hauteur dépend de l'équilibre.</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>Proportionnel à la hauteur, de $\log n$ à $n$ selon la forme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on suit une seule branche, la plus à gauche ; sa<br/>
longueur est au plus la hauteur, logarithmique si l'arbre est<br/>
équilibré, linéaire s'il est filiforme.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Constant, le minimum étant toujours à la racine de l'arbre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la racine est la première clé insérée, pas la plus<br/>
petite.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Toujours en $\log n$, quelle que soit la forme de l'arbre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : dans un arbre filiforme penché à gauche, la branche<br/>
gauche contient tous les nœuds.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Toujours en $n$, tous les nœuds devant être comparés</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : inutile de visiter les sous-arbres droits, qui ne<br/>
contiennent que des clés plus grandes.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q34 : Les sous-arbres d'un arbre binaire de recherche</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Le sous-arbre droit d'un arbre binaire de recherche est-il<br/>
lui-même un arbre binaire de recherche ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La définition récursive d'un arbre binaire de recherche impose la<br/>
propriété à chaque nœud : chaque sous-arbre la satisfait.</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, tout sous-arbre d'un arbre binaire de recherche en est un</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la propriété d'ordre s'applique à chaque nœud,<br/>
donc à la racine du sous-arbre droit comme à toutes les autres.<br/>
C'est ce qui permet les algorithmes récursifs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Non, seul l'arbre entier respecte la propriété d'ordre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la propriété est locale à chaque nœud, elle vaut dans<br/>
tout sous-arbre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Oui, sauf s'il est réduit à une feuille, qui n'a pas d'ordre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une feuille est un arbre binaire de recherche à un<br/>
seul nœud.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Non, ses clés étant toutes plus grandes que la racine</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : être plus grandes que la racine n'empêche pas ces<br/>
clés d'être ordonnées entre elles.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q35 : Une clé mal placée malgré l'ordre local</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>La racine porte $8$, son fils gauche porte $3$, et ce fils<br/>
gauche a pour fils droit $9$. Cet arbre est-il un arbre binaire<br/>
de recherche ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La propriété d'ordre est globale : toutes les clés du sous-arbre<br/>
gauche sont inférieures à la racine, toutes celles du droit<br/>
supérieures.</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>Non, $9$ est dans le sous-arbre gauche de $8$ mais lui est supérieur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : $9 &gt; 3$, l'ordre local est respecté, mais<br/>
toute clé du sous-arbre gauche de $8$ doit être inférieure à<br/>
$8$. La propriété porte sur des sous-arbres entiers, pas<br/>
seulement sur les enfants directs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Oui, chaque enfant droit étant plus grand que son parent direct</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : vérifier chaque nœud avec son seul parent ne suffit<br/>
pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Non, $3$ ne devrait pas avoir d'enfant droit, seulement un gauche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un enfant droit de $3$ est permis, à condition d'être<br/>
compris entre $3$ et $8$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Non, $8$ devrait être la plus petite clé, étant la racine</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la racine n'a aucune raison d'être la plus petite<br/>
clé.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q36 : Le nombre d'arbres binaires de recherche possibles</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Combien d'arbres binaires de recherche différents peut-on former<br/>
avec les clés $1$ à $3$ ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le nombre $C(n)$ d'arbres binaires de recherche à $n$ clés vérifie<br/>
$C(n) = C(0)C(n-1) + C(1)C(n-2) + \cdots + C(n-1)C(0)$, selon la<br/>
racine choisie : $1, 2, 5, 14, 42, \ldots$</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$, en distinguant selon la racine</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on choisit la racine, puis une forme pour les<br/>
clés plus petites et une pour les plus grandes : deux formes avec $1$ à la racine, une avec $2$, deux avec $3$, soit<br/>
$5$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$6$, un par ordre d'insertion</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : des ordres d'insertion différents peuvent donner le<br/>
même arbre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$3$, un par choix de racine</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une fois la racine choisie, les sous-arbres ont encore<br/>
plusieurs formes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$4$, un par répartition gauche ou droite</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la place d'une clé n'est pas un simple choix gauche<br/>
ou droite indépendant des autres.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q37 : Le parcours droite, nœud, gauche</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Sur un arbre binaire de recherche, on parcourt récursivement le<br/>
sous-arbre droit, puis le nœud, puis le sous-arbre gauche.<br/>
Qu'obtient-on ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Inverser gauche et droite dans le parcours infixe inverse l'ordre<br/>
de sortie des clés.</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>Les clés dans l'ordre décroissant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est le parcours infixe inversé ; les clés les<br/>
plus grandes, à droite, sortent en premier.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les clés dans l'ordre croissant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'ordre croissant vient du parcours gauche, nœud,<br/>
droit.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les clés dans l'ordre d'insertion</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun parcours ne restitue l'ordre d'insertion.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les feuilles seulement, de droite à gauche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : tous les nœuds sont visités, pas seulement les<br/>
feuilles.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q38 : Une recherche écrite avec une boucle</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle ligne complète cette recherche itérative de <code>x</code> dans un<br/>
arbre binaire de recherche de nœuds <code>Noeud</code> ?<br/>
<pre><code>def contient(racine, x):
    noeud = racine
    while noeud is not None:
        if x == noeud.valeur:
            return True
        # ligne à compléter
    return False</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La version itérative suit le même chemin que la version récursive,<br/>
en remplaçant l'appel par une mise à jour de <code>noeud</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="100" format="html">
    <text><![CDATA[<p><code>noeud = noeud.gauche if x &lt; noeud.valeur else noeud.droit</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : une clé plus petite ne peut être qu'à gauche,<br/>
une plus grande qu'à droite ; on descend d'un niveau à chaque<br/>
tour.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>noeud = noeud.droit if x &lt; noeud.valeur else noeud.gauche</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les côtés sont inversés, la recherche manquerait les<br/>
clés présentes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>noeud = noeud.gauche</code>, la clé étant toujours à gauche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : toujours descendre à gauche ne trouve que les clés de<br/>
la branche gauche.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>noeud = racine</code>, pour repartir du haut à chaque tour</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : revenir à la racine ferait boucler sans fin.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q39 : Supprimer une feuille</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment supprimer une clé située sur une feuille d'un arbre<br/>
binaire de recherche, sans casser la propriété d'ordre ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La suppression d'une feuille est le cas simple ; la suppression<br/>
d'un nœud à deux enfants demande de le remplacer par une clé<br/>
voisine.</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>Remplacer par <code>None</code> le lien que son parent tient vers elle</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la feuille n'a pas d'enfant, la retirer ne<br/>
déplace aucune autre clé ; l'ordre des clés restantes est<br/>
inchangé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Remplacer sa valeur par celle de la racine, puis supprimer la racine</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la valeur de la racine n'a rien à faire à cet endroit<br/>
de l'arbre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Décaler toutes les clés plus grandes d'un cran vers la gauche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un arbre n'est pas un tableau, rien ne se décale.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Mettre sa valeur à <code>None</code> en laissant le nœud dans l'arbre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un nœud sans valeur fausserait les comparaisons et les<br/>
parcours.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q40 : Supprimer un nœud à deux enfants</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On veut supprimer une clé dont le nœud a deux enfants. Par quelle<br/>
clé la remplacer pour conserver la propriété d'ordre ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le remplaçant doit être compris entre tout le sous-arbre gauche et<br/>
tout le sous-arbre droit : seuls le successeur et le prédécesseur<br/>
conviennent.</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>La plus petite clé de son sous-arbre droit</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : cette clé est plus grande que tout le<br/>
sous-arbre gauche et plus petite que le reste du sous-arbre<br/>
droit ; elle prend la place sans rien déranger, et son ancien<br/>
nœud, qui n'a pas d'enfant gauche, s'enlève facilement. La plus<br/>
grande clé du sous-arbre gauche convient aussi.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La clé de la racine, en descendant le reste</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la racine n'est en général ni plus grande que le<br/>
sous-arbre gauche ni plus petite que le droit.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>N'importe quelle feuille de l'arbre, au choix</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une feuille quelconque n'a aucune raison d'être<br/>
comprise entre les deux sous-arbres.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La plus grande clé de son sous-arbre droit</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : elle serait plus grande que des clés restées dans le<br/>
sous-arbre droit.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Arbres binaires de recherche — Q41 : La place d'une clé nouvellement insérée</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Où se retrouve une clé que l'on vient d'insérer dans un arbre<br/>
binaire de recherche, par l'algorithme habituel ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'insertion ne modifie jamais la structure existante : elle ne<br/>
fait qu'ajouter 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>Sur une nouvelle feuille, au bout du chemin de recherche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : l'insertion descend comme une recherche jusqu'à<br/>
un sous-arbre vide, et y crée un nœud sans enfant.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À la racine, les autres nœuds descendant d'un niveau</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la racine ne change jamais lors d'une insertion<br/>
simple.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Entre deux nœuds existants, au milieu du chemin</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun nœud n'est déplacé ni intercalé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À la place du nœud dont la clé est la plus proche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : remplacer un nœud perdrait sa clé.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
