C'est pas mieux l'intelligence artificielle ? apprendre a apprendre ? connaitre descartes et darwin ? pour des jeunes au collège ou au lycée ?
bon tant pis pour moi...
pour les pros du pyhton, chatgpt a bon en dessous ? si oui ca m'a pris 10 minutes pour traiter a l'heure ou les futurs profs normaux sont encore en examen

examen education nationale capes informatique 20/03/24 3ème concours
La correction selon ChatGpt :
QUESTION 1 - Voici une fonction récursive en Python pour rechercher une clé dans un arbre binaire de recherche :
python
Copy code
class Noeud:
def __init__(self, clef: int, gauche=None, droite=None):
self.gauche = gauche
self.droite = droite
self.clef = clef
def recherche_noeud(noeud: Noeud, k: int) -> bool:
"""
Recherche récursive d'une clé dans un arbre binaire de recherche.
:param noeud: Le nœud à partir duquel commencer la recherche.
:param k: La clé à rechercher.
:return: True si la clé est trouvée, False sinon.
"""
# Si le nœud est None, la clé n'est pas trouvée
if noeud is None:
return False
# Si la clé est égale à la clé du nœud actuel, la clé est trouvée
if k == noeud.clef:
return True
# Si la clé est inférieure à la clé du nœud actuel, recherche dans le sous-arbre gauche
if k < noeud.clef:
return recherche_noeud(noeud.gauche, k)
# Si la clé est supérieure à la clé du nœud actuel, recherche dans le sous-arbre droit
if k > noeud.clef:
return recherche_noeud(noeud.droite, k)
# Exemple d'utilisation
# Création de l'arbre de la Figure 1
arbre = Noeud(42, Noeud(-15, Noeud(-6000), Noeud(12)), Noeud(177, None, None))
# Recherche de la clé 12 dans l'arbre
print(recherche_noeud(arbre, 12)) # Devrait afficher True
Cette fonction prend en entrée un nœud de départ dans l'arbre et une clé à rechercher. Elle effectue une recherche récursive dans l'arbre en suivant les règles des arbres binaires de recherche. Si la clé est trouvée, elle retourne True, sinon False.
Question #2: Complexité algorithmique de la fonction de recherche dans un arbre binaire de recherche (ABR) en fonction du nombre de nœuds de l'arbre :
La complexité de la fonction de recherche dépend de la hauteur de l'arbre dans le pire des cas. Dans un ABR équilibré, la hauteur est logarithmique par rapport au nombre de nœuds (O(log n)), ce qui représente le cas idéal. Cependant, dans le pire des cas, lorsque l'arbre est déséquilibré (par exemple, s'il ressemble à une liste chaînée), la hauteur de l'arbre devient linéaire par rapport au nombre de nœuds (O(n)).
Donc, la complexité de la fonction de recherche dans un ABR est O(h), où h est la hauteur de l'arbre. Dans le meilleur des cas (ABR équilibré), h est O(log n), et dans le pire des cas (ABR déséquilibré), h est O(n).
Question #3: Fonction de collecte des valeurs des clés des nœuds dans un ABR par ordre croissant :
Voici une fonction récursive pour collecter les valeurs des clés des nœuds dans un ABR par ordre croissant :
python
Copy code
def collecte_noeuds(noeud: Noeud) -> List[int]:
"""
Collecte récursive des valeurs des clés des nœuds dans un arbre binaire de recherche par ordre croissant.
:param noeud: Le nœud à partir duquel commencer la collecte.
:return: Une liste des valeurs des clés des nœuds dans l'arbre par ordre croissant.
"""
if noeud is None:
return []
# Collecte récursive des valeurs dans le sous-arbre gauche
valeurs_gauche = collecte_noeuds(noeud.gauche)
# Ajout de la valeur du nœud actuel
valeurs_gauche.append(noeud.clef)
# Collecte récursive des valeurs dans le sous-arbre droit
valeurs_droite = collecte_noeuds(noeud.droite)
# Concaténation des valeurs
return valeurs_gauche + valeurs_droite
# Exemple d'utilisation
valeurs_ordre_croissant = collecte_noeuds(arbre)
print(valeurs_ordre_croissant)
Cette fonction collecte les valeurs des clés des nœuds dans un ABR en suivant un parcours récursif en profondeur. Les valeurs sont collectées dans l'ordre croissant en parcourant d'abord le sous-arbre gauche, puis en ajoutant la valeur du nœud actuel, et enfin en parcourant le sous-arbre droit.
Question #4: Incohérence de l'algorithme proposé est_ABR_1 :
L'algorithme est_ABR_1 suppose incorrectement que vérifier les clefs de chaque nœud et de ses enfants est suffisant pour garantir que l'arbre est un ABR. Cependant, cet algorithme ne prend pas en compte les relations d'ordre entre les nœuds au niveau global de l'arbre. Un contre-exemple peut être un arbre où un nœud gauche a une clé plus grande que la clé de son parent, ce qui viole la propriété des ABR.
Question #5, #6 et #7: L'implémentation de l'algorithme correct est_ABR_2_aux :
Voici une implémentation de la fonction est_ABR_2_aux qui propage les intervalles de haut en bas et décide si l'arbre binaire courant est un arbre binaire de recherche :
python
Copy code
INF = float('-inf')
SUP = float('inf')
def est_ABR_2_aux(noeud: Noeud, inf: int, sup: int) -> bool:
"""
Vérifie si l'arbre binaire courant est un arbre binaire de recherche en propageant les intervalles.
:param noeud: Le nœud courant à vérifier.
:param inf: Borne inférieure de l'intervalle pour les clés des nœuds.
:param sup: Borne supérieure de l'intervalle pour les clés des nœuds.
:return: True si l'arbre binaire courant est un ABR, False sinon.
"""
if noeud is None:
return True
# Vérification de la condition de l'invariant structurel
if inf <= noeud.clef <= sup:
# Appel récursif sur le sous-arbre gauche et droit
return est_ABR_2_aux(noeud.gauche, inf, noeud.clef) and est_ABR_2_aux(noeud.droite, noeud.clef, sup)
else:
return False
# Exemple d'utilisation
est_ABR = est_ABR_2_aux(arbre, INF, SUP)
print(est_ABR)
Cette fonction utilise la méthode de propagation des intervalles pour vérifier si chaque nœud et ses sous-arbres respectent l'invariant structurel des ABR. Si oui, l'arbre est considéré comme un ABR, sinon, il ne l'est pas.
Question #8: Les arbres de la Figure 3 sont-ils des B-trees d'ordre 2 ?
Pour qu'un arbre soit considéré comme un B-tree d'ordre 2, il doit satisfaire certaines propriétés. En particulier, il doit respecter les conditions suivantes :
Chaque nœud (sauf la racine) doit contenir au moins 1 clé et au plus 3 clés.
Chaque nœud (sauf la racine) doit avoir au moins 2 enfants et au plus 4 enfants.
Les clés doivent être triées dans chaque nœud.
Tous les chemins de la racine à une feuille doivent avoir la même longueur.
Examinons chaque arbre de la Figure 3 pour voir s'ils satisfont ces conditions :
(a) Arbre 1 :
Chaque nœud (sauf la racine) contient au moins 1 clé et au plus 3 clés.
Chaque nœud (sauf la racine) a au moins 2 enfants et au plus 4 enfants.
Les clés sont triées dans chaque nœud.
Tous les chemins de la racine à une feuille ont la même longueur.
Conclusion : Oui, l'arbre 1 est un B-tree d'ordre 2.
(b) Arbre 2 :
Ne satisfait pas la condition de tri des clés dans chaque nœud (les clés ne sont pas triées).
Conclusion : Non, l'arbre 2 n'est pas un B-tree d'ordre 2.
(c) Arbre 3 :
Chaque nœud (sauf la racine) contient au moins 1 clé et au plus 3 clés.
Chaque nœud (sauf la racine) a au moins 2 enfants et au plus 4 enfants.
Les clés sont triées dans chaque nœud.
Tous les chemins de la racine à une feuille ont la même longueur.
Conclusion : Oui, l'arbre 3 est un B-tree d'ordre 2.
Question #9: Écrire une fonction récursive d'impression d'un B-tree
Voici une implémentation de la méthode print_node dans la classe BTreeNode pour imprimer les nœuds du B-tree :
python
Copy code
class BTreeNode:
def __init__(self, t: int, is_leaf: bool = False):
self.is_leaf = is_leaf
self.keys = []
self.children = []
self.order = t
self.n = 0
def print_node(self, level=0):
print("Niveau", level)
for i in range(self.n):
print(self.keys, end=" ")
print()
if not self.is_leaf:
for child in self.children:
child.print_node(level + 1)