771 lines
22 KiB
Plaintext
771 lines
22 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Les arbres binaires\n",
|
|
"\n",
|
|
"> Parmi la forêt d'arbres possibles, on s'intéressera essentiellement aux arbres dit binaires.\n",
|
|
"> Ceux ci sont principalement utilisés pour les bases de données (indexation), les moteurs de recherche, et les compilateurs."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Définition\n",
|
|
"\n",
|
|
"Un arbre **binaire** est un arbre de degré 2 (dont les noeuds sont de degré 2 au plus).\n",
|
|
"\n",
|
|
"Les enfants d'un noeud sont lus de **gauche à droite** et sont appelés **fils gauche** et **fils droit**.\n",
|
|
"\n",
|
|
""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Exercice 1\n",
|
|
"\n",
|
|
"Parmi les arbres du cours précédent, lesquels sont binaires ?\n",
|
|
"\n",
|
|
"**Réponse :**"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Remarque\n",
|
|
"\n",
|
|
"Les arbres binaires forment une structure de données qui peut se définir de façon récursive.\n",
|
|
"\n",
|
|
"Un arbre binaire est:\n",
|
|
"- soit vide\n",
|
|
"- soit composé d'une racine portant une étiquette (clé) et d'une paire d'arbres binaires, appelés sous-arbre gauche et sous-arbre droit.\n",
|
|
"\n",
|
|
"Les arbres binaires sont utilisés dans de très nombreuses activités informatiques, nous allons étudier et implanter cette structure de données."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"---\n",
|
|
"\n",
|
|
"## Comment représenter un arbre binaire... à la main...\n",
|
|
"\n",
|
|
"L'idée est de représenter l'arbre avec un tableau.\n",
|
|
"\n",
|
|
"`[r, a, b]` La racine r suivie de ses fils gauche et droit.\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"Puis on rajoute dans l'ordre les fils gauche et droit de a, puis ceux de b.\n",
|
|
"\n",
|
|
"`[r, a, b, c, d, e, f]`"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Remarque\n",
|
|
"\n",
|
|
"Chaque noeud se repère par son indice *n* dans la liste, son fils gauche se trouvant alors à l'indice *2n + 1* et son fils droit à l'indice *2n + 2*.\n",
|
|
"\n",
|
|
"**Exemple:** **b** est d'indice 2, son fils gauche se trouve alors à l'indice 5 et son fils droit à l'indice 6.\n",
|
|
"\n",
|
|
"Si un noeud n'a pas de fils, on le précise en mettant *None* à sa place. Notre arbre est alors représenté par le tableau:\n",
|
|
"\n",
|
|
"`[r, a, b, c, d, e, f, None, None, None, None, None, None, None, None]`"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Quelle taille doit avoir le tableau ?\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"Cet arbre est complet (tous les noeuds internes ont deux fils).\n",
|
|
"\n",
|
|
"Il possède 3 niveaux, sa hauteur ou profondeur est donc de 2. La taille du tableau sera de:\n",
|
|
"\n",
|
|
"$$2^0 + 2^1 + 2^2 + 2^3 = 2^4 -1 = 15$$\n",
|
|
"\n",
|
|
"*Il faut compter le nombre de noeuds, y compris les noeuds \"fantômes\" des feuilles.*"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Exercice 2\n",
|
|
"\n",
|
|
"1. Quelle est la taille du tableau qui permet de représenter cet arbre ?\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"2. Écrire le tableau représentant cet arbre et le stocker dans une variable **t**\n",
|
|
"\n",
|
|
"3. Quelle propriété ont les indices des fils gauches et droits ?\n",
|
|
"\n",
|
|
"4. Voici un tableau représentant un arbre binaire. Le dessiner. Que peut-il représenter ?"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Tableau de la question 4\n",
|
|
"arbre_expression = ['*', '-', 5, 2, 6, None, None, None, None, None, None, None, None, None, None]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Question 2 : Écrire le tableau représentant l'arbre\n",
|
|
"t = # À compléter"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Code Python pour créer un arbre\n",
|
|
"\n",
|
|
"Voici un code Python qui crée la liste représentant l'arbre de l'exercice 2 :"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def creation_arbre(r, profondeur):\n",
|
|
" \"\"\"r : la racine (str ou int). la profondeur de l'arbre (int)\"\"\"\n",
|
|
" Arbre = [r] + [None for i in range(2**(profondeur+1)-2)]\n",
|
|
" return Arbre\n",
|
|
"\n",
|
|
"def insertion_noeud(arbre, n, fg, fd):\n",
|
|
" \"\"\"Insère les noeuds et leurs enfants dans l'arbre\"\"\"\n",
|
|
" indice = arbre.index(n)\n",
|
|
" arbre[2*indice+1] = fg\n",
|
|
" arbre[2*indice+2] = fd\n",
|
|
"\n",
|
|
"# création de l'arbre\n",
|
|
"arbre = creation_arbre(\"r\", 5)\n",
|
|
"# ajout des noeuds par niveau de gauche à droite\n",
|
|
"insertion_noeud(arbre, \"r\", \"a\", \"b\")\n",
|
|
"insertion_noeud(arbre, \"a\", \"c\", \"d\")\n",
|
|
"insertion_noeud(arbre, \"b\", \"e\", \"f\")\n",
|
|
"insertion_noeud(arbre, \"c\", None, \"h\")\n",
|
|
"insertion_noeud(arbre, \"d\", \"i\", \"j\")\n",
|
|
"insertion_noeud(arbre, \"e\", \"k\", None)\n",
|
|
"insertion_noeud(arbre, \"f\", None, None)\n",
|
|
"insertion_noeud(arbre, \"h\", None, None)\n",
|
|
"insertion_noeud(arbre, \"i\", None, None)\n",
|
|
"insertion_noeud(arbre, \"j\", \"m\", None)\n",
|
|
"insertion_noeud(arbre, \"k\", None, None)\n",
|
|
"insertion_noeud(arbre, \"m\", None, None)\n",
|
|
"\n",
|
|
"# pour vérifier\n",
|
|
"print(\"Taille du tableau :\", len(arbre))\n",
|
|
"print(\"Arbre :\", arbre)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Exercice 3\n",
|
|
"\n",
|
|
"1. Écrire une fonction qui retourne le parent d'un noeud s'il est dans l'arbre et None sinon.\n",
|
|
"2. Écrire une fonction qui retourne **True** si l'arbre est vide\n",
|
|
"3. Écrire une fonction qui retourne les enfants d'un noeud.\n",
|
|
"4. Une fonction qui renvoie le fils gauche d'un noeud s'il existe et None sinon\n",
|
|
"5. Même question pour le fils droit\n",
|
|
"6. Écrire une fonction qui renvoie **True** si le noeud est la racine de l'arbre\n",
|
|
"7. Écrire une fonction qui renvoie **True** si le noeud est une feuille\n",
|
|
"8. Écrire une fonction qui renvoie **True** si le noeud comporte un frère gauche ou droit.\n",
|
|
"\n",
|
|
"**Rappel : dans un tableau, si on note i l'indice d'un noeud, alors ses fils auront comme indice 2i+1 et 2i+2.**\n",
|
|
"\n",
|
|
"**Inversement, pour trouver le parent d'un noeud, il faut calculer : (i-1) // 2**"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Question 1 : Parent d'un noeud\n",
|
|
"def parent(arbre, noeud):\n",
|
|
" \"\"\"Retourne le parent du noeud s'il existe, None sinon\"\"\"\n",
|
|
" pass # À compléter"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Question 2 : Arbre vide\n",
|
|
"def est_vide(arbre):\n",
|
|
" \"\"\"Retourne True si l'arbre est vide\"\"\"\n",
|
|
" pass # À compléter"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Question 3 : Enfants d'un noeud\n",
|
|
"def enfants(arbre, noeud):\n",
|
|
" \"\"\"Retourne les enfants du noeud\"\"\"\n",
|
|
" pass # À compléter"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Question 4 : Fils gauche\n",
|
|
"def fils_gauche(arbre, noeud):\n",
|
|
" \"\"\"Retourne le fils gauche s'il existe, None sinon\"\"\"\n",
|
|
" pass # À compléter"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Question 5 : Fils droit\n",
|
|
"def fils_droit(arbre, noeud):\n",
|
|
" \"\"\"Retourne le fils droit s'il existe, None sinon\"\"\"\n",
|
|
" pass # À compléter"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Question 6 : Est racine\n",
|
|
"def est_racine(arbre, noeud):\n",
|
|
" \"\"\"Retourne True si le noeud est la racine\"\"\"\n",
|
|
" pass # À compléter"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Question 7 : Est feuille\n",
|
|
"def est_feuille(arbre, noeud):\n",
|
|
" \"\"\"Retourne True si le noeud est une feuille\"\"\"\n",
|
|
" pass # À compléter"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Question 8 : A un frère\n",
|
|
"def a_frere(arbre, noeud):\n",
|
|
" \"\"\"Retourne True si le noeud a un frère\"\"\"\n",
|
|
" pass # À compléter"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"---\n",
|
|
"\n",
|
|
"## Une seconde façon de faire...\n",
|
|
"\n",
|
|
"Comme vous l'avez sans doute constaté, il est assez fastidieux de représenter un arbre avec un unique tableau surtout pour un arbre très profond.\n",
|
|
"\n",
|
|
"L'idée est de représenter l'arbre avec un tableau contenant des tableaux.\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"Cet arbre se représente par le tableau:\n",
|
|
"\n",
|
|
"`['r', ['a', [], []], ['b', [], []]]`"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Exercice 4\n",
|
|
"\n",
|
|
"Écrire le tableau représentant l'arbre ci-dessous et le stocker dans une variable **t**\n",
|
|
"\n",
|
|
""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Exercice 4 : Représentation avec tableaux imbriqués\n",
|
|
"t = # À compléter"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Construction récursive avec dictionnaires\n",
|
|
"\n",
|
|
"Le code Python ci-dessous construit l'arbre de manière récursive.\n",
|
|
"\n",
|
|
"* Les noeuds sont représentés par un dictionnaire.\n",
|
|
"* L'arbre se construit depuis la racine en construisant les sous-arbres des fils gauche et droit."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def noeud(nom, fg=None, fd=None):\n",
|
|
" return {'racine': nom, 'fg': fg, 'fd': fd}\n",
|
|
"\n",
|
|
"# création des noeuds\n",
|
|
"k = noeud('k')\n",
|
|
"f = noeud('f')\n",
|
|
"e = noeud('e', k, None)\n",
|
|
"b = noeud('b', e, f)\n",
|
|
"m = noeud('m')\n",
|
|
"j = noeud('j', m, None)\n",
|
|
"i = noeud('i')\n",
|
|
"d = noeud('d', i, j)\n",
|
|
"h = noeud('h')\n",
|
|
"c = noeud('c', None, h)\n",
|
|
"a = noeud('a', c, d)\n",
|
|
"racine = noeud('r', a, b)\n",
|
|
"\n",
|
|
"# création de l'arbre sous forme de liste imbriquée\n",
|
|
"def construit(arbre):\n",
|
|
" if arbre is None:\n",
|
|
" return []\n",
|
|
" else:\n",
|
|
" return [arbre['racine'], construit(arbre['fg']), construit(arbre['fd'])]\n",
|
|
"\n",
|
|
"arbre1 = construit(racine)\n",
|
|
"print(arbre1)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Exercice 5\n",
|
|
"\n",
|
|
"Écrire toutes les fonctions de l'exercice 3 dans le cas de cette implémentation de l'arbre (tableaux imbriqués)."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Exercice 5 : Fonctions pour tableaux imbriqués\n",
|
|
"# À compléter"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"---\n",
|
|
"\n",
|
|
"## Hauteur et parcours d'un arbre\n",
|
|
"\n",
|
|
"Nous allons maintenant nous intéresser à la hauteur de l'arbre, ainsi qu'aux différentes façons de le parcourir:\n",
|
|
"* Le parcours en largeur\n",
|
|
"* Le parcours en profondeur (parcours préfixe, parcours infixe et parcours suffixe)."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Calcul de la hauteur de l'arbre\n",
|
|
"\n",
|
|
"L'idée est la suivante:\n",
|
|
"* Si l'arbre est vide, la hauteur vaut -1\n",
|
|
"* Sinon la hauteur vaut 1 auquel il faut ajouter le maximum entre les hauteurs des sous-arbres gauche et droit.\n",
|
|
"* Ces sous-arbres sont eux-mêmes des arbres dont il faut calculer la hauteur.\n",
|
|
"\n",
|
|
"Une méthode **récursive** semble donc tout à fait adaptée à la situation.\n",
|
|
"\n",
|
|
""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Exercice 6\n",
|
|
"\n",
|
|
"Écrire cette fonction pour l'arbre précédent et vérifier que sa profondeur est de 4."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Exercice 6 : Hauteur de l'arbre\n",
|
|
"def hauteur(arbre):\n",
|
|
" \"\"\"Retourne la hauteur de l'arbre\"\"\"\n",
|
|
" pass # À compléter\n",
|
|
"\n",
|
|
"# Test\n",
|
|
"# print(hauteur(arbre1)) # Doit afficher 4"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"---\n",
|
|
"\n",
|
|
"## Les parcours\n",
|
|
"\n",
|
|
"### Le parcours en largeur\n",
|
|
"\n",
|
|
"Le parcours en largeur d'un arbre consiste à partir de la racine. On visite ensuite son fils gauche puis son fils droit, puis le fils gauche du fils gauche etc... Comme le montre le schéma ci-dessous:\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"L'idée est la suivante:\n",
|
|
"\n",
|
|
"On utilise une **File**.\n",
|
|
"* On met l'arbre dans la file.\n",
|
|
"* Puis tant que la file n'est pas vide:\n",
|
|
" * On défile la file\n",
|
|
" * On récupère sa racine\n",
|
|
" * On enfile son fils gauche s'il existe\n",
|
|
" * On enfile son fils droit s'il existe\n",
|
|
"\n",
|
|
""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Exercice 7\n",
|
|
"\n",
|
|
"1. Rappeler les fonctions permettant de définir une structure de file en Python.\n",
|
|
"2. Implémenter alors cette fonction et l'essayer sur l'arbre précédent."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Exercice 7 : Parcours en largeur\n",
|
|
"def parcours_largeur(arbre):\n",
|
|
" \"\"\"Parcours en largeur de l'arbre\"\"\"\n",
|
|
" pass # À compléter"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Les parcours en profondeur\n",
|
|
"\n",
|
|
"On se balade autour de l'arbre en suivant les pointillés.\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"Voici un algorithme permettant de réaliser ce parcours:\n",
|
|
"\n",
|
|
""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Exercice 8\n",
|
|
"\n",
|
|
"Proposer une fonction permettant de réaliser le parcours en profondeur d'un arbre."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Exercice 8 : Parcours en profondeur\n",
|
|
"def parcours_profondeur(arbre):\n",
|
|
" \"\"\"Parcours en profondeur de l'arbre\"\"\"\n",
|
|
" pass # À compléter"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Les trois types de parcours en profondeur\n",
|
|
"\n",
|
|
"Dans le schéma ci-dessus, on a rajouté des \"noeuds fantômes\" pour montrer que l'on peut considérer que chaque noeud est visité trois fois:\n",
|
|
"* une fois par la gauche\n",
|
|
"* une fois par en dessous\n",
|
|
"* une fois par la droite\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"**Définition - Parcours préfixe :**\n",
|
|
"Dans un parcours **préfixe**, on liste le noeud la **première fois** qu'on le rencontre.\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"**Définition - Parcours infixe :**\n",
|
|
"Dans un parcours **infixe**, on liste le noeud la **seconde fois** qu'on le rencontre.\n",
|
|
"\n",
|
|
"Ce qui correspond à:\n",
|
|
"* On liste chaque noeud ayant un fils gauche la seconde fois qu'on le voit\n",
|
|
"* On liste chaque noeud sans fils gauche la première fois qu'on le voit\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"**Définition - Parcours suffixe :**\n",
|
|
"Dans un parcours **suffixe**, on note le noeud la **dernière fois** qu'on le rencontre."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Exercice 9\n",
|
|
"\n",
|
|
"Écrire les sommets dans l'ordre d'un parcours préfixe."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"**Réponse :**"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Exercice 10\n",
|
|
"\n",
|
|
"Écrire les sommets dans l'ordre d'un parcours infixe."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"**Réponse :**"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Exercice 11\n",
|
|
"\n",
|
|
"Écrire les sommets dans l'ordre d'un parcours suffixe."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"**Réponse :**"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Exercice 12\n",
|
|
"\n",
|
|
"1. Voici trois algorithmes récursifs, dire pour chacun d'entre eux à quel parcours il correspond.\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"2. Implémenter ces trois fonctions en Python et confirmer les réponses des questions précédentes."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Exercice 12 : Implémentation des trois parcours\n",
|
|
"\n",
|
|
"def parcours_1(arbre):\n",
|
|
" \"\"\"Premier algorithme - À identifier\"\"\"\n",
|
|
" pass # À compléter\n",
|
|
"\n",
|
|
"def parcours_2(arbre):\n",
|
|
" \"\"\"Deuxième algorithme - À identifier\"\"\"\n",
|
|
" pass # À compléter\n",
|
|
"\n",
|
|
"def parcours_3(arbre):\n",
|
|
" \"\"\"Troisième algorithme - À identifier\"\"\"\n",
|
|
" pass # À compléter"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"---\n",
|
|
"\n",
|
|
"## Une troisième façon de faire... en programmation objet\n",
|
|
"\n",
|
|
"Nous allons créer une classe **Noeud** dont les attributs d'instances seront:\n",
|
|
"* le nom (ou valeur) de la racine\n",
|
|
"* son fils gauche (None par défaut) ou de type Noeud\n",
|
|
"* son fils droit (None par défaut) ou de type Noeud"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Exercice 13\n",
|
|
"\n",
|
|
"1. Implémentez cette classe Noeud\n",
|
|
"2. Stocker l'arbre comme étant l'objet de type \"Noeud\" correspondant à la racine.\n",
|
|
"3. Écrire une méthode `est_feuille` qui renvoie True si le noeud est une feuille et False sinon\n",
|
|
"4. Définir une fonction `hauteur` prenant comme argument un arbre permettant de renvoyer la hauteur de cet arbre\n",
|
|
"5. Écrire une méthode `hauteur` dans la classe Noeud permettant de faire la même chose\n",
|
|
"6. Proposer des fonctions pour le parcours infixe, préfixe et suffixe pour cette façon de coder un arbre.\n",
|
|
"7. Transformer alors vos fonctions en méthodes de la classe Noeud"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Exercice 13 : Classe Noeud\n",
|
|
"\n",
|
|
"class Noeud:\n",
|
|
" def __init__(self, valeur, gauche=None, droit=None):\n",
|
|
" \"\"\"Constructeur de la classe Noeud\"\"\"\n",
|
|
" pass # À compléter\n",
|
|
" \n",
|
|
" def est_feuille(self):\n",
|
|
" \"\"\"Retourne True si le noeud est une feuille\"\"\"\n",
|
|
" pass # À compléter\n",
|
|
" \n",
|
|
" def hauteur(self):\n",
|
|
" \"\"\"Retourne la hauteur de l'arbre\"\"\"\n",
|
|
" pass # À compléter\n",
|
|
" \n",
|
|
" def parcours_prefixe(self):\n",
|
|
" \"\"\"Parcours préfixe de l'arbre\"\"\"\n",
|
|
" pass # À compléter\n",
|
|
" \n",
|
|
" def parcours_infixe(self):\n",
|
|
" \"\"\"Parcours infixe de l'arbre\"\"\"\n",
|
|
" pass # À compléter\n",
|
|
" \n",
|
|
" def parcours_suffixe(self):\n",
|
|
" \"\"\"Parcours suffixe de l'arbre\"\"\"\n",
|
|
" pass # À compléter"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Construction de l'arbre avec la classe Noeud\n",
|
|
"# À compléter"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"---\n",
|
|
"\n",
|
|
"### Sources\n",
|
|
"\n",
|
|
"- [Cours de Stephan Van Zulen](https://www.nsi-ljm.fr/NSI-TLE/co/section_chapitre3.html)\n",
|
|
"- [Cours de Jeremy Camponovo](https://github.com/jcamponovo)"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.9"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
}
|