T.P. 4 : des arbres binaires variés et leurs applications

Documents pareils
Les arbres binaires de recherche

1 Recherche en table par balayage

Représentation d un entier en base b

Exercices types Algorithmique et simulation numérique Oral Mathématiques et algorithmique Banque PT

Cours 1 : Introduction Ordinateurs - Langages de haut niveau - Application

STAGE IREM 0- Premiers pas en Python

Projet d informatique M1BI : Compression et décompression de texte. 1 Généralités sur la compression/décompression de texte

UEO11 COURS/TD 1. nombres entiers et réels codés en mémoire centrale. Caractères alphabétiques et caractères spéciaux.

Travaux pratiques. Compression en codage de Huffman Organisation d un projet de programmation

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Compression de Données - Algorithme de Huffman Document de Conception

Architecture des Systèmes d Information Architecture des Systèmes d Information

Licence Sciences et Technologies Examen janvier 2010

Quelques Algorithmes simples

Manuel d utilisation 26 juin Tâche à effectuer : écrire un algorithme 2

Cours d introduction à l informatique. Partie 2 : Comment écrire un algorithme? Qu est-ce qu une variable? Expressions et instructions

Programmation linéaire

Définitions. Numéro à préciser. (Durée : )

Continuité et dérivabilité d une fonction

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

III- Raisonnement par récurrence

LES CARTES À POINTS : POUR UNE MEILLEURE PERCEPTION

Souad EL Bernoussi. Groupe d Analyse Numérique et Optimisation Rabat http ://

Les structures de données. Rajae El Ouazzani

TP1 - Prise en main de l environnement Unix.

Initiation à l algorithmique

Fonctions de plusieurs variables

Bases de programmation. Cours 5. Structurer les données

L exclusion mutuelle distribuée

ÉPREUVE COMMUNE DE TIPE Partie D

Indications pour une progression au CM1 et au CM2

Initiation à Excel. Frédéric Gava (MCF)

V- Manipulations de nombres en binaire

Chapitre 5 : Flot maximal dans un graphe

Algorithmes récursifs

Initiation à la Programmation en Logique avec SISCtus Prolog

Projet L1, S2, 2015: Simulation de fourmis, Soutenance la semaine du 4 mai.

Recherche dans un tableau

La NP-complétude. Johanne Cohen. PRISM/CNRS, Versailles, France.

EVALUATION Nombres CM1

TS 35 Numériser. Activité introductive - Exercice et démarche expérimentale en fin d activité Notions et contenus du programme de Terminale S

Cours 7 : Utilisation de modules sous python

SOCLE COMMUN - La Compétence 3 Les principaux éléments de mathématiques et la culture scientifique et technologique

TP 1. Prise en main du langage Python

TP : Gestion d une image au format PGM

DM 1 : Montre Autoquartz ETA

ARBRES BINAIRES DE RECHERCHE

# let rec concat l1 l2 = match l1 with [] -> l2 x::l 1 -> x::(concat l 1 l2);; val concat : a list -> a list -> a list = <fun>

MATLAB : COMMANDES DE BASE. Note : lorsqu applicable, l équivalent en langage C est indiqué entre les délimiteurs /* */.

Calcul matriciel. Définition 1 Une matrice de format (m,n) est un tableau rectangulaire de mn éléments, rangés en m lignes et n colonnes.

Représentation des Nombres

Raisonnement par récurrence Suites numériques

Le produit semi-direct

Limites finies en un point

«Dire et écrire» pour réaliser une composition en travail collaboratif en géographie. Agnès Dullin, lycée J. Racine 20 rue du Rocher, Paris

LES TYPES DE DONNÉES DU LANGAGE PASCAL

MIS 102 Initiation à l Informatique

Ensimag 1ère année Algorithmique 1 Examen 2ième session 24 juin Algorithmique 1

avec des nombres entiers

Chapitre 3. Les distributions à deux variables

TP3 : Manipulation et implantation de systèmes de fichiers 1

INF601 : Algorithme et Structure de données

Définition 0,752 = 0,7 + 0,05 + 0,002 SYSTÈMES DE NUMÉRATION POSITIONNELS =

Consigne : je remplis le tableau en tenant compte des informations de la ligne supérieure et de la colonne de gauche (droite pour les gauchers)

Probabilités conditionnelles Exercices corrigés

Cours Informatique Master STEP

ET 24 : Modèle de comportement d un système Boucles de programmation avec Labview.

introduction Chapitre 5 Récursivité Exemples mathématiques Fonction factorielle ø est un arbre (vide) Images récursives

TD 1 - Structures de Traits et Unification

1 Définition et Appel d une fonction. V. Phan Luong. Cours 4 : Fonctions

Théorie et Codage de l Information (IF01) exercices Paul Honeine Université de technologie de Troyes France

Objets Combinatoires élementaires

Probabilités. Rappel : trois exemples. Exemple 2 : On dispose d un dé truqué. On sait que : p(1) = p(2) =1/6 ; p(3) = 1/3 p(4) = p(5) =1/12

Introduction à l étude des Corps Finis

TP 1 Prise en main de l environnement Unix

chapitre 4 Nombres de Catalan

Arbres binaires de recherche

Initiation à la programmation en Python

Les indices à surplus constant

Chapitre 1 : Évolution COURS

Arithmétique binaire. Chapitre. 5.1 Notions Bit Mot

Exercices du Cours de la programmation linéaire donné par le Dr. Ali DERBALA

Exercices de dénombrement

Structure fonctionnelle d un SGBD

1 de 46. Algorithmique. Trouver et Trier. Florent Hivert. Mél : Florent.Hivert@lri.fr Page personnelle : hivert

Corrigé des TD 1 à 5

Baccalauréat S Antilles-Guyane 11 septembre 2014 Corrigé

Chapitre 2 Le problème de l unicité des solutions

Algorithmique et Programmation, IMA

Programmation Web. Madalina Croitoru IUT Montpellier

Python - introduction à la programmation et calcul scientifique

Cours d Analyse. Fonctions de plusieurs variables

Modèles à Événements Discrets. Réseaux de Petri Stochastiques

Cours 1 : La compilation

Programmation C. Apprendre à développer des programmes simples dans le langage C

Logiciel Libre Cours 3 Fondements: Génie Logiciel

Premiers Pas en Programmation Objet : les Classes et les Objets

LES TOUT PREMIERS PAS

Projet Matlab : un logiciel de cryptage

Transcription:

T.P. 4 : des arbres binaires variés et leurs applications 1 Arbres binaires de recherche 1.1 Ce qu on doit déjà savoir sur la recherche d un mot dans une liste triée et après... Supposons par exemple qu on veuille constituer et manipuler un lexique anglais/français. Un tel lexique sera représenté en Python par une liste de couples de mots, comme par exemple : lexique = [( blue, bleu ),( green, vert ),( red, rouge ),( yellow, jaune )] On suppose que les mots anglais sont rangés dans l ordre du dictionnaire (comme dans l exemple précédent). Cet ordre est l ordre implanté en python sur les chaines de caractères avec le symbole <. Notons aussi que pour les couples, python commence par comparer les premières entrées. On suppose donc qu on dispose d une variable globale lexique comme ci-dessus. a) Sachant que la liste des mots anglais est triée dans l ordre du dictionnaire, écrire une fonction traduit qui reçoit un mot anglais en argument (qui est supposé être dans le lexique) et renvoie sa traduction avec une complexité en O(log(n)) où n est la longueur du lexique. N.B. La complexité logarithmique demande une méthode de dichotomie. b) Ecriture une fonction insere qui reçoit un argument qui est un couple (motanglais, motfrancais) qui permet de rajouter ce couple à la bonne place dans la variable globale lexique : cette fonction sera de complexité linéaire. Le problème : la représentation de notre lexique sous cette forme fait que la fonction insere a une complexité en O(n). Nous allons maintenant présenter une nouvelle façon de coder le lexique, une autre structure de donnée, où l insertion, comme la recherche, d un mot dans le lexique, sera en O(log(n)). 1.2 Présentation des arbres binaires de recherche Définition mathématique 1 : un arbre sera pour nous un ensemble de points appelés noeuds muni d une relation pour laquelle chaque noeud a un père et un seul (on représente la relation père fils par une flèche), sauf un noeud qui n a pas de père qu on appelle la racine. On convient de représenter la racine en haut et les pères en dessus de leurs fils. Si le noeud p est le père du noeud f on dit aussi que f est un fils de p. Les noeuds qui n ont pas de fils sont appelés feuilles. Définition mathématique 2 : un arbre au sens précédent sera dit arbre binaire si chaque père a au plus deux fils, appelés alors fils droit et fils gauche. Lien avec notre problème : Chaque noeud sera un élément de notre ensemble de couples (motanglais,motfrancais). La relation père/fils entre les mots sera définie au niveau des parties motanglais (la partie motanglais du couple est ce qu on appelle la clé d enregistrement). 1

Par exemple, avec un lexique à quatre mots : ici la racine sera le couple dont blue est la clé, avec deux fils de clés red et yellow et red a un fils green Définition 3 : définition informatique d un arbre binaire, avec son implantation python : un arbre binaire est une structure de donnée qui peut être définie récursivement comme suit : un arbre binaire est : soit vide, codé comme une liste vide [], soit codé comme une liste [racine, filsgauche, filsdroit] où racine est un couple (motanglais,motfrancais), et filsdroits et filsgauche sont deux arbres binaires. Exemple : Avec Arbrelexique=[( blue, bleu ),filsgauche,filsdroit] où filsgauche=[( red, rouge ),[],[( green, vert ),[],[]]] et filsdroit=[( yellow, jaune ),[],[]], on aura le codage informatique de l arbre binaire dessiné ci-dessus. Définition 4 : arbre binaire de recherche : un arbre [racine, filsgauche, filsdroit] au sens de la définition 3 est un arbre binaire de recherche si, et seulement si, la clé de racine est strictement supérieure à la clé de tous les noeuds de filsgauche, la clé de racine est strictement inférieure à la clé de tous les noeuds de filsdroit, filsdroit et filsgauche sont des arbres binaires de recherche. L exemple précédent ne donne pas un arbre binaire de recherche mais la version modifiée suivante oui : 1.3 Implantation en python de la fabrication récursive des arbres binaires de recherche... et recherche! On considère donc des arbres binaires de recherche comme définis au paragraphe précédents, dont les noeuds sont des couples (motanglais,motfrancais) que l on compare pour l ordre lexicographique des mots anglais. a) Ecrire trois fonctions filsgauche, filsdroit, racine qui prennent en argument un arbre binaire de recherche arbre et renvoie respectivement son fils Gauche, son fils Droit, et sa racine. 2

b) On veut écrire alors une fonction récursive ajout(element, arbre) qui prend comme argument un élément i.e. un couple (motanglais,motfrancais) et un arbre binaire (qui au départ peut être vide, ce sera notre cas de base) et qui retourne un nouvel arbre binaire de recherche où element est incorporé à arbre. N.B. on doit comparer les mots anglais. Pour cela, le principe est le suivant : si le mot anglais de l élément à rajouter est plus grand que le mot anglais à la racine de l arbre, on construit un arbre binaire en gardant la même racine, le même fils gauche, et on se ramène au problème de rajouter l élément au fils droit. si le mot anglais de l élément à rajouter est plus petit que le mot anglais à la racine de l arbre... à vous de deviner! Ecrire la fonction python correspondante! Par commodité pour la suite, on considérera aussi le cas où le mot qu on rajoute est déjà présent dans l arbre : dans ce cas bien sûr l arbre ne devra pas être modifié. c) Appliquer la fonction précédente pour fabriquer un arbre binaire de recherche pour notre lexique en ajoutant successivement les éléments de la liste suivante : lexique = [( red, rouge ),( blue, bleu ),( yellow, jaune ),( green, vert )] d) Ecrire enfin une fonction récursive traduit2(mot,arbre) qui renvoie la traduction d un mot anglais qui est stocké dans un arbre binaire de recherche comme précédemment. (On comparera mot à la (partie anglaise de la) racine de l arbre, et si ils sont différents, ensuite récursivement soit à filsdroit soit à filsgauche..) 1.4 Complexités : arbres équilibrés a) Définition : la hauteur (on dit aussi profondeur) d un noeud de l arbre est le nombre de générations qui le séparent de la racine de l arbre. Cette hauteur admet naturellement une définition récursive rigoureuse (laquelle?) En déduire une fonction récursive hauteur(element, arbre) qui renvoie la hauteur du noeud element supposé présent dans l arbre arbre. b) Par définition la hauteur de l arbre est la maximum des hauteurs des éléments. On dira qu un arbre ayant n noeuds est équilibré ssi sa hauteur est minimale parmi tous les arbres ayant n noeuds. Donner en l expliquant, une relation entre la hauteur h d un arbre équilibré et son nombre total de noeuds n. Le dessin suivant, qui est un cas particulier devrait suffire pour comprendre! N.B. Pour les questions qui suivent, on admet qu on peut toujours ranger nos données dans un arbre binaire de recherche équilibré 1. c) Justifiez que la fonction traduit2 du paragraphe précédent, appliquée à un arbre équilibré, est de complexité O(log(n)) où n est le nombre de noeuds de l arbre. d) La fonction ajout du paragraphe précédent fabrique-t-elle forcément des graphes équilibrés? e) Montrer en tous cas que si on applique cette fonction ajout a un arbre équilibré ayant n noeuds, la complexité de l ajout est en O(log(n)). 1. en fait il existe bien des algorithmes pour s y ramener, en faisant des rotations 3

Moralité : par rapport à ce qu on a dit au tout premier paragraphe, les arbres binaires de recherche équilibrés ont l avantage qu aussi bien la recherche que l ajout d une donnée sont en O(log(n)). 2 Une classe python fabriquée suivant les principes du 1 : les dictionnaires python La classe dictionary n est pas au programme, dans une épreuve d écrit on devrait vous la présenter! a) Au 1, on a expliqué (modulo le problème d équilibrage des arbres!) comment fabriquer une structure qui permet de gérer un dictionnaire de n mots avec une complexité en O(log(n)) pour la recherche et l ajout d un mot. En python, il existe une structure qui fait exactement cela, la classe dict. Par exemple dico={ red : rouge, blue : bleu, yellow : jaune } sera un dictionnaire avec trois entrées, les mots en anglais ici seront les clés qui servent à accéder aux valeurs qu elles référencent (ici les mots en français). Voici quelques commandes de cette classe : a={} # création d un dictionnaire vide appelé a a[ truc ]=12 # création d une entrée du dictionnaire avec la valeur 12 et à la clé truc # eh oui c est exactement ce qu on ne peut pas faire avec les listes.. pas de out of range ici a[ truc ] # va renvoyer la valeur 12. dico[ red ] # va renvoyer rouge yellow in dico # va renvoyer True black in dico # va renvoyer False Question (exemple) écrire une fonction freq qui prend en paramètre une chaîne de caractères comme CABBAA et renvoie un dictionnaire où les lettres sont les clés et le nombre d occurrence de chaque lettre est la valeur stockée pour chaque clés. Ainsi freq( CABBAA ) renverra { A : 3, B : 2, C : 1}. Noter qu il n y a pas d ordre défini entre les clés d un dictionnaire. b) Quelque précision sur le parcours des dictionnaires : (i) Avec dico comme ci-dessus, que donne le code : for a in dico: print(a) (ii) Comment faire alors pour voir à la fois les clés et les valeurs qu elles référencent dans le dictionnaire dico? Créer une fonction ListeCouple qui prend en argument un dictionnaire et renvoie une liste des couples (clé,valeur). Par exemple ListeCouple(dico) renverra (à l ordre près) : [( blue, bleu ), ( red, rouge ), ( yellow, jaune )] 3 Tri avec la construction d un arbre binaire de recherche On a vu au 1.3 comment on pouvait transformer une liste en arbre binaire de recherche. Explicitement, à l aide de la fonction ajout définie dans ce paragraphe, écrire une fonction ABR qui fabrique un tel arbre à partir d une liste. Ainsi pour L=[34,2,667,1,4,20], ABR(L) donnera : [34, [2, [1, [], []], [4, [], [20, [], []]]], [667, [], []]] Expliquer ce que fait alors la fonction suivante, appliquée la variable arbre ci-dessus, et à la liste vide t=[] : def parcoursprofondeur(arbre,t): if arbre!=[]: t=parcoursprofondeur(filsgauche(arbre),t) 4

t.append(racine(arbre)) t=parcoursprofondeur(filsdroit(arbre),t) return t En déduire une méthode pour trier une liste (par exemple une liste de nombres) qui commence par transformer cette liste en arbre binaire de recherche. 4 Les tas et le tri par tas 4.1 La structure de tas : encore un arbre binaire Définition : un tas binaire, ici on dira simplement un tas (en anglais heap) est un arbre binaire (comme au 1) qui est ordonné de sorte que la clé d un noeud est toujours supérieure à la clé de ses fils (de sorte que son plus grand élément est toujours la racine de l arbre) 2. Du point de vue informatique, on va ici coder simplement ces arbres par un tableau (liste python) de nombres. Par exemple T=[9,5,6,2,1,5,1,0] codera l arbre cicontre. Cet arbre est bien un tas, puisque chaque père a une valeur supérieur à celles de ses fils. L intérêt des tas pour les tris : Au 3, on a expliqué comment obtenir un algorithme de tri en transformant une liste en arbre binaire de recherche. Ici c est bien plus immédiat avec les tas puisque si on sait ranger les données en un tas, à chaque fois la première entrée donnera le max. de la liste. 4.2 Organisation en tas But de cette partie : prendre une liste quelconque et la réorganiser en un tas. On va donc gérer les tas à l aide de listes pythons : chaque liste python sera interprétée mentalement par nous comme associée à un arbre binaire (qui n est pas forcément un tas). Par exemple pour T=[5,2,6,0,1,9,1,5] 2. En fait, il s agit de tas-max, en remplaçant supérieur par inférieur, on a la notion de tas-min. 5

Ainsi, on ne manipule que des listes simples, la structure d arbre n apparaît pas dans le codage, mais il faut comprendre que pour chaque i où cela a un sens T[i] a pour fils T[2i+1] et T[2i+2]. A l inverse le père de T[i] est T[(i-1)//2]. Par commodité, on notera pere(i) pour (i-1)//2, gauche(i)=2*i+1 et droite(i)=2i+2. a) Ecrire une fonction estuntas qui reçoit une liste T et renvoie True ou False ssi T représente un tas. b) Avec les hypothèses 0 i limite et limite longueur(t), écrire un fonction maximum(t,i,limite) qui retourne le plus petit entier imax vérifiant toutes les conditions suivantes : imax<limite et imax {i,gauche(i),droite(i)} T[iMax] T[i] gauche(i)<limite T[iMax] T[gauche(i)] droite(i)<limite T[iMax] T[droite(i)] En d autres termes maximum(t,i,limite) retourne l indice (inférieur à limite) de la plus grande des trois valeurs T[i], T[gauche(i)], T[droite(i)]. En cas de valeurs égales, le plus petit indice est retourné. Par exemple, avec tableau T ci-dessus, max(t,0,8)=2 puisque T[0]=5, T[1]=2, et T[2]=6, donc la valeur maximum est atteinte pour i=2. c) Soit la fonction récursive Python suivante : def entasserrecursif(t,i,limite): imax=maximum(t,i,limite) if imax!=i: echange(t,i,imax) entasserrecursif(t,imax,limite) avec : def echange(t,i,j): aux=t[i] T[i]=T[j] T[j]=aux On fait l appel de entasserrecursif(t,0,8) où T est la liste représentant l arbre suivant : Dessiner l arbre représentant T après cet appel de entasserrécursif(t,0,8) d) L algorithme entasserrecursif(t,i,limite) échange des valeurs du tableau de haut en bas, en suivant une branche de l arborescence. Cela a pour effet de faire descendre des petites valeurs, et de faire monter les grandes valeurs. Il est donc possible de construire un tas, en itérant cet algorithme sur les indices décroissants du tableau. Construire ainsi une fonction construiretas(t) qui transforme un tableau T en tas. e) En déduire un algorithme de tri, qui prend une liste et la trie (par ordre décroissant), grâce à la structure de tas. 6