Plan Piqûre de rappel sur les références Evaluation d'expressions arithmétiques Variables et méthodes statiques Vocabulaire sur les arbres Amphi 4 1
Retour sur les références class Code { int numero; Code(int n) { numero = n; Amphi 4 2
Retour sur les références (2) static void f(int c) { c = 4321; static void g(code c) { c.numero = 4321; Amphi 4 3
Retour sur les références (3) public static void main(string[] args) { Code c = new Code(1234); System.out.println(c.numero); f(c.numero); System.out.println(c.numero); g(c); System.out.println(c.numero); Qu'affiche le programme? Amphi 4 4
Plan Piqûre de rappel sur les références Evaluation d'expressions arithmétiques Variables et méthodes statiques Vocabulaire sur les arbres Amphi 4 5
Arbre d'une expression arithmétique ((a/((b-c)+d))*(e-a))*c * * c / - a + e a - d b c Amphi 4 6
Notation postfixée (polonaise) ((a/((b-c)+d))*(e-a))*c * Forme postfixée abc-d+/ea-*c* Les opérandes sont écrits avant l'opérateur * / - a + e a - d c b c Amphi 4 7
Evaluation des expressions arithmétiques Beaucoup plus simple sous forme postfixée. Utilisation d'une pile. Une seule règle : lorsqu'un opérateur est en entrée, on dépile les opérandes et on empile le résultat. 6 3 2-1 + / 9 6 - * - + / - * 2 3 6 1 6 1 1 6 2 6 3 9 3 6 9 3 3 3 9 (6/(3-2+1))*(9-6) Amphi 4 8
Expressions arithmétiques en Java (1) class Terme { boolean estnombre; int nombre; char operateur; Amphi 4 9
Expressions arithmétiques en Java (2) Trois méthodes principales class ExpressionPostfixe { static int calculer(int x, char a, int y) {... static void evaluer(terme x, Pile p) {... static int evaluer(terme[] u) {... Amphi 4 10
Expressions arithmétiques en Java (3) static int calculer(int x, char a, int y) { switch (a) { case '+': return x + y; case '-': return x - y; case '*': return x * y; case '/': return x / y; return -1; // sinon Amphi 4 11
Expressions arithmétiques en Java (4) static void evaluer(terme x, Pile p) throws PileException { if (x.estnombre) Pile.ajouter(x.nombre, p); else { int a = Pile.valeur(p); Pile.supprimer(p); int b = Pile.valeur(p); Pile.supprimer(p); int c = calculer(b, x.operateur, a); Pile.ajouter(c, p); // variante dans le poly Amphi 4 12
Expressions arithmétiques en Java (5) static int evaluer(terme[] u) throws PileException { Pile p = new Pile(); for (int i = 0; i < u.length ; ++i) evaluer(u[i], p); return Pile.valeur(p); // variante dans le poly Amphi 4 13
Evaluation d'une expression (6) try { int valeur = evaluer(expression); System.out.println("La valeur est " + valeur); catch (PileException e) { System.out.println("Erreur dans l'évaluation"); Amphi 4 14
Plan Piqûre de rappel sur les références Evaluation d'expressions arithmétiques Variables et méthodes statiques Vocabulaire sur les arbres Amphi 4 15
Variables statiques (1) Une variable déclarée static est commune à tous les objets de la classe. Pour cette raison, on parle de variable de classe. Toute modification d'une variable statique dans un objet quelconque de la classe est visible par tous les objets de la classe. Exemple : Math.Pi (Pi est une variable final static de la classe Math) Variable non statique --> une instance par objet. Amphi 4 16
Variables statiques (2) class Paire { static int x; int y; Amphi 4 17
Variables statiques (2) class Test { static void main() { Paire s = new Paire(); System.out.println("s.x = " + s.x + ", s.y = " + s.y + ", Paire.x = " + Paire.x); >s.x = 0, s.y = 0, Paire.x = 0 Amphi 4 18
Variables statiques (3) class Test { static void main() { Paire s = new Paire (); Paire t = new Paire (); t.x = 2; t.y = 3; System.out.println("t.x = " + t.x + ", t.y = " + t.y); System.out.println("s.x = " + s.x + ", s.y = " + s.y); >t.x = 2, t.y = 3 >s.x = 2, s.y = 0 Amphi 4 19
Méthodes statiques Une méthode déclarée static peut être utilisée sans référence à un objet particulier. On parle alors de méthode de classe. Une méthode statique n'a pas directement accès aux variables non statiques. On peut appeler une méthode statique par NomdeClasse.nomDeMethode() Exemple : Math.abs() (abs() est une méthode statique de la classe Math) Amphi 4 20
Méthodes non statiques Une méthode qui n'est pas déclarée static est toujours utilisée en référence à un objet. On parle de méthode d'objet. On peut appeler une méthode non statique par nomobjet.nomdemethode() Le mot clé this désigne l'objet courant. Il n'a jamais la valeur null, et sa valeur ne peut être modifiée. Utiliser this dans une méthode statique produit une erreur à la compilation. Amphi 4 21
System.out.println() La classe System contient une variable de classe de nom out. L'objet System.out appelle une méthode d'objet de nom println(). Amphi 4 22
Méthodes statiques (2) class Paire { static int x; int y; void affiche_x() { // méthode d'objet System.out.println("s.x = " + this.x); void affiche_y() { // méthode d'objet System.out.println("s.y = " + this.y); static void affiche2_x() { // de classe System.out.println("s.x = " + x); static void affiche3_y(paire s) { System.out.println("s.y = " + s.y); Amphi 4 23
Méthodes statiques (3) class Test { static void main() { Paire s = new Paire(); Paire t = new Paire(); t.x = 2; t.y = 3; s.affiche_x(); s.affiche_y(); Paire.affiche2_x(); s.affiche2_x(); Paire.affiche3_y(s); // s.affiche3_y(s) serait maladroit Amphi 4 24
Méthodes statiques (3) > s.x = 2 // s.affiche_x(); > s.y = 0 // s.affiche_y(); > s.x = 2 // Paire.affiche2_x(); > s.x = 2 // s.affiche2_x(); > s.y = 0 // Paire.affiche3_y(); Amphi 4 25
Méthodes statiques (4) class Paire { static int x; int y; void affiche_y() { // méthode d'objet System.out.println("s.y = " + this.y); /*static void affiche2_y() { System.out.println("s.y = " + y); Erreur : y n'est pas "static"! */ Amphi 4 26
Files statiques class File { // méthode statique static void ajouter(int x, File f) {...; class Usage { // usage statique File f = new File(); File.ajouter(7, f); Amphi 4 27
Files non statiques class FileNS { // méthode non statique void ajouter(int x) {...; class UsageNS { // usage non statique FileNS f = new FileNS(); f.ajouter(7); Amphi 4 28
Plan Piqûre de rappel sur les références Evaluation d'expressions arithmétiques Variables et méthodes statiques Vocabulaire sur les arbres Amphi 4 29
Un arbre de hauteur 4 0 Racine 1 2 Nœuds internes 3 4 Feuilles Amphi 4 30
Parents, enfants, arité 1 Le nœud 3 a quatre enfants. C'est un nœud d'arité 4. 2 3 4 Le parent de 5 est 2. 5 6 7 8 9 10 11 12 13 14 15 Amphi 4 31
Une définition récursive des arbres Un arbre est un ensemble fini de nœuds, tel que : (1) Il existe un nœud particulier appelé racine, (2) Les nœuds restants sont partitionnés en ensembles qui sont eux mêmes des arbres. 1 2 3 4 T = (1, {(2, {(5), (6)), (3, {(7), (8), (9)), (4)) 5 6 7 8 9 Amphi 4 32
Un arbre orienté est un arbre dans lequel l'ensemble des enfants de chaque nœud est totalement ordonné. Exemple : la table des matières d'un livre. Arbres orientés 1 2 3 chapitres 1.1 1.2 2.1 2.2 2.3 paragraphes Amphi 4 33
Un arbre binaire est une structure de données définie sur un ensemble fini de nœuds, qui est soit vide, Arbres binaires soit union disjointe d'une racine, d'un arbre binaire appelé sous-arbre gauche, et d'un arbre binaire appelé sous-arbre droit. Attention! Un arbre binaire n'est pas simplement un arbre ordonné dont tous les nœuds sont d'arité 2 Amphi 4 34
Deux arbres binaires distincts 6 6 2 8 2 8 4 9 5 4 9 5 7 1 3 7 1 3 Amphi 4 35
class Arbre { Arbre filsg; int contenu; Arbre filsd; Les arbres binaires en Java Arbre(Arbre a, int v, Arbre b) { filsg = a; contenu = v; filsd = b; Amphi 4 36
Parcours d'arbres binaires 1 Préfixe (CGD) : 1, 2, 4, 8, 9, 5, 10, 3, 6, 7 2 3 Infixe (GCD) : 8, 4, 9, 2, 10, 5, 1, 6, 3, 7 4 5 6 7 8 9 10 Postfixe (GDC) : 8, 9, 4, 10, 5, 2, 6, 7, 3, 1 Amphi 4 37
Parcours en largeur 1 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 2 3 4 5 6 7 8 9 10 Amphi 4 38
Parcours préfixe en Java static void ParcoursPrefixe(Arbre a) { if (a == null) return; System.out.print(a.contenu + " "); ParcoursPrefixe(a.filsG); ParcoursPrefixe(a.filsD); Amphi 4 39
Parcours infixe et postfixe en Java static void ParcoursInfixe(Arbre a) { if (a == null) return; ParcoursInfixe(a.filsG); System.out.print(a.contenu + " "); ParcoursInfixe(a.filsD); static void ParcoursPostfixe(Arbre a) { if (a == null) return; ParcoursPostfixe(a.filsG); ParcoursPostfixe(a.filsD); System.out.print(a.contenu + " "); Amphi 4 40
Parcours en itératif En itératif, le parcours préfixe est réalisé à l'aide d'une pile. Le parcours en largeur est réalisé à l'aide d'une file. Amphi 4 41
Parcours préfixe à l'aide d'une pile Empiler la racine; Tant que la pile n'est pas vide { afficher le sommet de pile et le supprimer; empiler le fils droit; empiler le fils gauche 8 4 5 6 7 1 2 4 8 9 5 10 3 6 7 9 2 10 1 3 1 2 3 4 5 3 8 9 5 3 9 5 3 5 3 10 3 6 3 7 Amphi 4 42 7
Parcours préfixe itératif (1) class Pile { final static int maxp = 50; int hauteur; Arbre[] contenu; Pile() { hauteur = 0; contenu = new Arbre[maxP]; boolean estvide() { return hauteur == 0; Amphi 4 43
Parcours préfixe itératif (2) class Pile { // méthodes d'objet... //... void ajouter(arbre x) { contenu[hauteur++] = x; Arbre valeur() { return contenu[hauteur-1]; void supprimer() { hauteur--; Amphi 4 44
Parcours préfixe itératif (3) static void parcoursprefixei(arbre a) { if (a == null) return; Pile p = new Pile(); p.ajouter(a); while (!p.estvide()) { a = p.valeur(); p.supprimer(); System.out.print(a.contenu + " "); if (a.filsd!= null) p.ajouter(a.filsd); if (a.filsg!= null) p.ajouter(a.filsg); Amphi 4 45
Parcours en largeur à l'aide d'une file Ajouter la racine; Tant que la file n'est pas vide { afficher le début de la file et le supprimer; 1 ajouter le fils gauche; ajouter le fils droit; Amphi 4 46 8 4 5 6 7 1 2 3 4 5 6 7 8 9 10 2 3 3 4 4 5 6 6 7 7 8 9 9 10 10 5 10 5 6 7 7 8 9 8 9 10 8 9 10 9 2 10 1 3
Parcours en largeur itératif (1) class File { final static int MaxF = 30; int debut; int fin; Arbre[] contenu; File() { debut = 0; fin = 0; contenu = new Arbre[MaxF]; static int successeur(int i) { return (i+1) % MaxF; Amphi 4 47
Parcours en largeur itératif (2) boolean estvide() { return (debut == fin); Arbre valeur() { return contenu[debut]; void ajouter(arbre x) { contenu[fin] = x; fin = successeur(fin); void supprimer() { debut = successeur(debut); Amphi 4 48
Parcours en largeur itératif (3) static void parcourslargeuri(arbre a) { if (a == null) return; File f = new File(); f.ajouter(a); while (!f.estvide()) { a = f.valeur(); f.supprimer(); System.out.print(a.contenu + " "); if (a.filsg!= null) f.ajouter(a.filsg); if (a.filsd!= null) f.ajouter(a.filsd); Amphi 4 49
Obtention de la forme postfixée (1) On utilise une pile pour obtenir la forme postfixée. ((6 / (3-2 + 1)) * (9-6) * 2) 6 3 2-1 + / 9 6 - * 2 * Amphi 4 50
On lit l'expression pas à pas. Trois règles (1) Si on a un entier, on l'affiche. (2) Si on a (, on l'empile avec priorité 0 (3) Si on a ), on dépile en affichant jusqu'à (. (4) Si on a un opérateur +, -, *, / : tant que (priorité du sommet de pile priorité du caractère) afficher puis effacer le sommet de pile. Puis empiler le caractère entrant. Règles Priorité des opérateurs : ) / * + - ( 3 2 2 1 1 0 Amphi 4 51
Obtenir : 6 3 2-1 + / 9 6 - * 2 * ((6 / (3-2 + 1)) * (9-6) * 2) 0( 0( 6 2/ 0( 3 1-2 1+ 1 3) 1-1- 1+ 0( 2/ 0( 0( 0( 0( 0( 0( 2/ 2/ 2/ 2/ 2/ 0( 0( 0 ( 0( 0( 0( 0( 0( 0( 0( 0( 0( 0( 0( 0( 3) 2* 0( 9 1-6 3) 2* 2 3) 2/ 0( 0( 0( 0( 2 * 0( 2* 0( 0( 2* 0( 1-0( 2* 0( Amphi 4 52 1-0( 2* 0( 2* 0( 2* 0( 2* 0( 1+ 0( 2/ 0( 0(