DICTIONNAIRES (MAPS)
OBJECTIFS Apprendre à utiliser le type de données “Map” (dictionnaire) Comprendre le fonctionnement des arbres binaires de recherche Voir l’implantation du type “Map” (dictionnaire) avec un arbre binaire de recherche 9/8/2019 IFT1020
CODES Map.java BSTNode.java BST.java BSTMap.java 9/8/2019 IFT1020
Map (dictionnaire) Une map (un dictionnaire) garde les associations entre des clés et des valeurs. Chaque clé dans une map (un dictionnaire) est unique. Une valeur peut cependant être associée à plusieurs clés. 9/8/2019 IFT1020
Map Les classes qui implantent l’interface Map BSTMap (pas dans lib. Standard) HashMap TreeMap 9/8/2019 IFT1020
Un exemple de Map 9/8/2019 IFT1020
Déclaration et utilisation d’une BSTMap //Créer une BSTMap Map monDictionnaire = new BSTMap(); //Ajouter une entrée monDictionnaire.put(“AAGA“, mot(19)); //Changer une entrée monDictionnaire.put(“AAGA",mot(23)); 9/8/2019 IFT1020
Accès (get) et suppression (remove) //Obtenir la valeur associée à une clé Mot motCourant = monDictionnaire.get(“AGAA"); //Supprimer une entrée monDictionnaire.remove(“AGAA"); 9/8/2019 IFT1020
Imprimer les paires clé/valeur Set cles = monDictionnaire.keySet(); Iterator i = cles.iterator(); while(i.hasNext()) { Object cle = i.next(); Object val = monDictionnaire.get(cle); System.out.println(cle + "->" + val); } 9/8/2019 IFT1020
Classes et interface Map dans la librairie standard 9/8/2019 IFT1020
Arbres binaires de recherche Les arbres binaires de recherche permettent l’insertion et la suppression d’éléments dans O(log n) -- plus rapide que dans une liste ! Un arbre binaire est constitué d’un groupe de nœuds. Chaque nœud contient un élément et au plus deux autres noeuds : ses enfants gauche et droit. Un nœud particulier, la racine, est le seul du groupe qui n’est ni l’enfant droit ni l’enfant gauche d’un autre nœud. Le nœud racine est accessible par l’entête (header) de l’arbre. Les propriétés d’ordre des nœuds sont les suivantes : Les descendants à gauche d’un nœud possèdent des valeurs plus petites que ce nœud. Les descendants à droite d’un nœud possèdent des valeurs plus grandes que ce nœud. 9/8/2019 IFT1020
Un arbre binaire de recherche racine Sous-arbre gauche Sous-arbre droit Enfants droits Enfants gauches Feuilles r g u h s w Taille = nombre de nœuds = 6 Arbre vide : taille = 0 (aucun nœud); racine = null 9/8/2019 IFT1020
Définition récursive Un arbre binaire est : (i) un arbre vide (ii) Contient une racine, un (sous-)arbre gauche et un (sous-)arbre droit (sous-)arbre gauche (sous-)arbre droit 9/8/2019 IFT1020
Arbre binaire balancé p = 2 Un arbre binaire de profondeur d est balancé si tous les nœuds aux profondeurs 0, 1, …, d-2 ont deux enfants. Les nœuds à la profondeur d-1 peuvent avoir 2, 1 ou aucun enfant (mais au moins 1 nœud en possède au moins 1 pour avoir un arbre de profondeur d). La profondeur d’un nœud est le nombre de liens à parcourir à partir de la racine pour le rejoindre. racine p = 0 r p = 2 p = 1 p = 1 g u p = 2 p = 2 p = 2 h s w La profondeur d’un arbre est la profondeur de plus profond nœud. 9/8/2019 IFT1020
Quelle est la profondeur d’un arbre binaire vide? racine Par convention, la profondeur d’un arbre binaire vide est -1. 9/8/2019 IFT1020
Balancé ? Donc, cet arbre est balancé ! Arbre de profondeur d = 2, tous les nœuds jusqu’à profondeur d-2 = 0 ont deux enfants et les nœuds à profondeur d-1 = 1 ont 2, 1 ou aucun enfant. racine d = 0 d = 1 Donc, cet arbre est balancé ! 9/8/2019 IFT1020
Balancé ? Donc, cet arbre n’est pas balancé ! racine Tous les nœuds jusqu’à profondeur d-2 ont deux enfants. d-2 Donc, cet arbre n’est pas balancé ! 9/8/2019 IFT1020
Propriétés des arbres binaires Un arbre binaire balancé de profondeur d possède au moins 2d et au plus 2d+1-1 nœuds. (a) balancé d = 2 22 = 4 nœuds. (b) balancé d = 2 23-1 = 7 nœuds. La profondeur d’un arbre binaire balancé de taille n = log2 n . Un arbre binaire non-balancé de profondeur d peut contenir aussi peu que d+1 nœuds. (c) non-balancé d = 3 3+1 = 4 nœuds. La profondeur maximum d’un arbre non-balancé de taille n = n – 1. 9/8/2019 IFT1020
Arbres binaires de recherche (ABR) Binary Search Trees (BST) (représentation graphique et récursive) Si un nœud possède l’élément « k » : - ABR gauche ne contient que des éléments < que k ou est vide. - ABR droit ne contient que des éléments > que k ou est vide. NB. Pas de duplicat (rappel : les clés dans un dictionnaire sont uniques. k < k ou vide > k ou vide 9/8/2019 IFT1020
Construire un ABR avec des chats lion tiger lynx puma leopard cheetah cougar 9/8/2019 IFT1020
search lion < > leopard tiger < < Yé! cheetah lynx > Plus grande, chercher à droite… droite.search(lynx); lynx lynx lion Plus petite, chercher à gauche… gauche.search(lynx); < > lynx leopard tiger < < lynx Yé! cheetah lynx > > cougar puma 9/8/2019 IFT1020
insert lion < > leopard tiger < < cheetah lynx > > Plus petite ! gauche == null; gauche = new BSTNode(leopard); Plus grande ! droite == null; droite = new BSTNode(tiger); racine != null; racine.insert(leopard); Plus petite ! gauche != null; gauche.insert(cougar); Plus petite ! gauche != null; gauche.insert(cheetah); Plus petite ! gauche == null; gauche = new BSTNode(cheetah); racine == null; racine = new BSTNode(lion); racine != null; racine.insert(cougar); racine != null; racine.insert(cheetah); racine != null; racine.insert(puma); Plus grande ! droite != null; droite.insert(puma) racine != null; racine.insert(lynx); lion Plus petite ! gauche != null; gauche.insert(cougar); Plus grande ! droite != null; droite.insert(lynx) Plus grande ! droite == null; droite = new BSTNode(cougar); tiger racine != null; racine.insert(tiger); lynx cougar cheetah lion leopard lynx tiger puma Plus petite ! gauche == null; gauche = new BSTNode(lynx); Plus petite ! gauche != null; gauche.insert(puma); puma lion leopard cheetah < > cheetah cougar lynx puma cougar leopard tiger Plus grande ! droite == null; droite = new BSTNode(puma); < < cougar puma cheetah lynx > > cougar puma 9/8/2019 IFT1020
Plus rien à gauche, Eureka ! delete Eureka ! Ce nœud possède des enfants gauche et droit. On doit donc trouver la plus petite clé à droite. element = droite.getLeftmost(); lion lion droite = droite.delete(element); Descendre à gauche… lynx lion ? < > delete(lynx) leopard tiger Copier lynx à la racine Plus rien à gauche, Eureka ! < < cheetah lynx > > cougar puma 9/8/2019 IFT1020
gauche = gauche.delete(lynx); Plus petite ! gauche = gauche.delete(lynx); lynx tiger < delete(lynx) lynx > puma 9/8/2019 IFT1020
delete lynx > puma lynx Eureka ! lynx 9/8/2019 IFT1020 gauche == null; return droite; lynx lynx > puma 9/8/2019 IFT1020
gauche = gauche.delete(lynx); Plus petite ! gauche = gauche.delete(lynx); return this; tiger < puma delete(lynx) 9/8/2019 IFT1020
delete lynx < > delete(lynx) tiger puma < leopard < Eureka ! Ce nœud possède des enfants gauche et droit. On doit donc trouver la plus petite clé à droite. element = droite.getLeftmost(); lion droite = droite.delete(element); return this; lynx < > delete(lynx) tiger puma < leopard < cheetah > cougar 9/8/2019 IFT1020
toString lion ( leopard ( cheetah ( [] , cougar ) , [] ) , tiger ( StringBuffer sb = new StringBuffer(); sb.append(element); if(gauche != null || droite != null) sb.append("(").append(gauche == null ? "[]" : "" + gauche).append(",").append(droite == null ? "" + droite).append(")"); lion < > leopard tiger < < cheetah lynx > > cougar puma lion ( leopard ( cheetah ( [] , cougar ) , [] ) , tiger ( lynx ( [] , puma ) , [] ) ) 9/8/2019 IFT1020
pprint lion < > leopard tiger < < cheetah lynx > > cougar puma 9/8/2019 IFT1020
size lion < > leopard tiger < < cheetah lynx > > 7 return 1 + (gauche == null ? 0 : gauche.size()) + (droite == null ? 0 : droite.size()); 1+ lion 3 3 < > 1+ 1+ leopard tiger 2 2 < < 1+ 1+ cheetah lynx 1 1 > > 1+ 1+ cougar puma 9/8/2019 IFT1020
elements lion < > leopard tiger < < cheetah lynx > > List l = new ArrayList(10); if(gauche != null) l.addAll(gauche.elements()); l.add(element); if(droite != null) l.addAll(droite.elements()); return l; [cheetah, cougar, leopard, lion, lynx, puma, tiger] [cheetah, cougar, leopard, lion, lynx, puma, tiger] [cheetah, cougar, leopard, lion] [cheetah, cougar, leopard] [] lion [lynx, puma, tiger] [cheetah, cougar, leopard] < > [cheetah, cougar, leopard] [cheetah, cougar] [] [lynx, puma, tiger] [lynx, puma] [] leopard tiger [lynx, puma] [cheetah, cougar] < < [cheetah, cougar] [cheetah] [] [lynx, puma] [lynx] [] cheetah lynx [puma] [cougar] > > [cougar] [] [puma] [] cougar puma 9/8/2019 IFT1020