• Aucun résultat trouvé

Plan •Arbres équilibrés–Arbres AVL–Arbres a-b•Quelques compléments de Java

N/A
N/A
Protected

Academic year: 2022

Partager "Plan •Arbres équilibrés–Arbres AVL–Arbres a-b•Quelques compléments de Java"

Copied!
54
0
0

Texte intégral

(1)

Plan

• Arbres équilibrés – Arbres AVL – Arbres a-b

• Quelques compléments de Java

(2)

Structures d'arbre

• Les structures d'arbre permettent de réaliser des opérations dynamiques, telles que recherche, prédécesseur, successeur, minimum, maximum, insertion, et suppression en temps proportionnel à la hauteur de l'arbre.

• Si l'arbre est équilibré, la hauteur est en O(log n) où n est le nombre de nœuds.

• Divers types d'arbres équilibrés sont utilisés : arbres AVL, 2-3, bicolores, b-arbres.

(3)

Arbres AVL : définition

Un arbre binaire est un arbre

AVL (Adelson-Velskii et Landis) si, pour tout sommet, les hauteurs des sous-arbres gauche et droit

diffèrent d’au plus 1.

0 0

1 2 1 0

3 2

4

0 1

0

(4)

Exemple : arbres de Fibonacci

(5)

Hauteur d’un arbre AVL

Propriété. Soit A un arbre AVL ayant n sommets et de hauteur h. Alors

log2(1+n) ≤ 1+ h ≤ a log2(2 + n) avec a ≤ 1,44.

Par exemple, si n = 100000, 17 ≤ h ≤ 25.

On a toujours

n ≤ 2h+1 - 1 donc log2(1+n) ≤ 1+ h .

(6)

Hauteur d’un arbre AVL (2)

Soit N(h) le nombre minimum de sommets d’un arbre AVL de hauteur h. Alors

N(h) = 1 + N(h-1) + N(h-2).

h-1 h-2

(7)

Hauteur d’un arbre AVL (2)

La suite F(h) = N(h)+1 vérifie

F(0) = 2, F(1) = 3, F(h+2) = F(h+1) + F(h) donc

F(h) = 1/√5 (fh+3 – f-(h+3)) où f = 1 +2÷ 5

est le nombre d'or

1 + n ≥ F(h) > 1/√5 (fh+3 – 1)

h+3 < log2(2+n) / log2 f + log2 √5 ≤ a log2(2+n) +2

(8)

Rotations et équilibrage

Les rotations gauche et droite transforment un arbre

• Elles préservent l'ordre infixe

• Elles se réalisent en temps constant.

q p

U V

W

q p

U

V W

gauche rotation

droite

(9)

Implantation (non destructive)

q p

U V

W

q p

U

V W

droite rotation

gauche

static Arbre rotationG(Arbre a) {

Arbre b = a.filsD;

Arbre c = new Arbre (a.filsG, a.contenu, b.filsG);

return new Arbre (c, b.contenu, b.filsD);

a

c b

(10)

Implantation (destructive)

q p

U V

W

q p

U

V W

droite rotation

gauche

static Arbre rotationG(Arbre a) { Arbre b = a.filsD;

a.filsD = b.filsG;

b.filsG = a;

return b;

a

b b

a

(11)

Double rotation

double rotation

droite r

p

U

q X

V W

q p

U V

r

W X

r q

p X

W

rotation gauche autour de p

rotation droite autour de r

(12)

Insertion dans un arbre AVL

• Insertion ordinaire, suivie de rééquilibrage.

71 44

37

83 61

50

50

71 44

37

83 61

61 44

37

71

83 50

double rotation autour de «71»

(13)

Insertion dans un arbre AVL

• Insertion ordinaire, suivie de rééquilibrage.

50

71 44

37

83 61

61 44

37

71

83 50

rotation droite autour de «71»

37

71 61

44

83

50 rotation gauche

autour de «44»

(14)

Propriétés

• Pour rééquilibrer un arbre AVL après une insertion, une seule rotation ou double rotation suffit.

• Pour rééquilibrer un arbre AVL après une

suppression, il faut jusqu’à h rotations ou double rotations (h est la hauteur de l'arbre).

(15)

Algorithme

Algorithme. Soit A un arbre, G et D ses sous- arbres gauche et droit. On suppose que

h(G) – h(D)  = 2

• Si h(G) – h(D) = 2, on fait une rotation droite.

Soient g et d les sous-arbres gauche et droit de G.

Si h(g) < h(d), on fait d'abord une rotation gauche de G.

Si h(G) – h(D) = -2, opérations symétriques.

(16)

Implantation : la classe AVL

class Avl {

char contenu;

int hauteur;

Avl filsG, filsD;

Avl(Avl g, char c, Avl d) { filsG = g;

contenu = c;

filsD = d;

hauteur = 1 + Math.max(H(g), H(d));

}

...

(17)

Implantation : calculs sur la hauteur

static int H(Avl a)

{ return (a == null) ? -1 : a.hauteur;

}

static void Avl calculerHauteur(Avl a) {

a.hauteur = 1 +

Math.max(H(a.filsG), H(a.filsD));

}

Toutes les méthodes sont dans la classe AVL.

(18)

Implantation des rotations

static Avl rotationG(Avl a) {

Avl b = a.filsD;

Avl c =

new Avl(a.filsG, a.contenu, b.filsG);

return

new Avl(c, b.contenu, b.filsD);

}

(19)

Implantation du rééquilibrage

static Avl equilibrer(Avl a) {

calculerHauteur(a);

if (H(a.filsG) - H(a.filsD) == 2) {

if (H(a.filsG.filsG) <

H(a.filsG.filsD))

a.filsG = rotationG(a.filsG);

return rotationD(a);

} // else

if (H(a.filsG)- H(a.filsD) == -2){...}

return a;

(20)

Implantation de l’insertion

static Avl inserer(int x, Avl a) {

if (a == null)

return new Avl(null, x, null);

if (x < a.contenu)

a.filsG = inserer(x, a.filsG);

else if (x > a.contenu)

a.filsD = inserer(x, a.filsD);

// seul changement : return equilibrer(a);

}

(21)

Pourquoi des b-arbres ?

• On doit souvent manipuler de grands volumes de données.

• Si les données ne tiennent pas en mémoire vive, les problèmes d'accès au disque deviennent primordiaux.

• Un seul accès au disque prend environ autant de temps que 200 000 instructions.

• L'utilisation d'un b-arbre minimise le nombre d'accès au disque.

(22)

Information sur disque

• Un disque est divisé en pages (par exemple de taille 512, 2048, 4096 ou 8192 octets).

• La page est l'unité de transfert entre mémoire et disque.

• Les informations sont constituées

d'enregistrements, accessibles par une clé.

• Une page contient plusieurs enregistrements.

• Problème : trouver la page contenant l'enregistrement de clé c.

(23)

Arbres de recherche généralisés

34 46 15

8 65

clés

≤ 8

clés

]8-15] clés ]15-34]

clés ]34-46]

clés ]46-65]

clés

> 65 Chaque noeud interne contient des balises

(24)

Arbres de recherche généralisés

Même principe que les arbres binaires de recherche

12 14 11

6

18 8

20 26 30 4 7 10 12 14 17 22 24

21 23 25

27 32

19

(25)

Définition d'un arbre a-b (2a - 1 ≤ b)

• C'est un arbre de recherche généralisé.

• Les feuilles ont toutes la même profondeur.

• La racine a au moins 2 et au plus b fils (sauf si l'arbre est réduit à sa racine).

• Les autres nœuds internes ont au moins a et au plus b fils.

• Lorsque b = 2a - 1, un arbre a-b est appelé un b- arbre d'ordre a-1.

• En pratique, a peut être de l'ordre de plusieurs

(26)

Un arbre 2-4

12 14 11

6

40 20

8

21 26 30 42

4 7 10 12 14 18 21 25 30 36 41 50

Clés Balises

c0 ≤ k1 < c1 ≤ ... ≤ kd < cd

(27)

Taille d'un arbre a-b (2a - 1 ≤ b)

Preuve. Tout nœud a au plus b fils. Il y a donc au plus bh feuilles. Tout nœud autre que la racine a au moins a fils, et la racine au moins 2. Au total, il y a au moins 2ah-1 feuilles.

Proposition. Si un arbre a-b de hauteur h contient n feuilles, alors 2ah-1 ≤ n ≤ bh et donc

log n / log b ≤ h ≤ 1 + log(n/2) / log a

(28)

Recherche dans un arbre a-b

12 14 11

6

40 20

8

21 26 30 42

4 7 10 12 14 18 21 25 30 36 41 50

Recherche de 30

(29)

Insertion dans un arbre a-b (1)

13 10

6

40 20

8

21 26 30 42

4 7 9 12 14 21 25 30 36 41 50

Insertion de 11:

la balise est min(11, 12)

13

10 10 11 13

(30)

Insertion dans un arbre a-b (2)

13 10

6

40 20

8

21 26 30 42

4 7 9 12 14 21 25 30 36 41 50

Insertion de 13 : la balise est

13

10 10 12 13

(31)

Eclatement d'un nœud

L'insertion d'un élément peut produire un nœud ayant plus de b fils. Il faut alors éclater le nœud.

21 26 27

21 25 27 30 30

36

21 21 25

27

27 30 30

36

26

(32)

12 14 11

6

40 20

8

21 26 30 42

4 7 10 12 14 18 21 25 30 36 41 50

Insertion de 15

12 14 11

40 20

8

15 14

11

20 12

8 40

A éclater !

(33)

12

11 6

40 20

8

21 26 30 42

4 7 10 12 14 18 21 25 30 36 41 50

Après insertion de 15

15

14 15

(34)

Fusion de deux nœuds

C'est l'opération inverse de l'éclatement.

21 26 27

21 25 27 30 30

36 21

21 25

27

27 30 30

36

26

(35)

Partage de deux nœuds

21 29 30 32 18 26

27

20 21 29 30

32 18 27

26

20

(36)

Suppression d'une feuille (1)

Algorithme.

• Supprimer la feuille, puis les balises figurant sur le chemin de la feuille à la racine.

• Si les nœuds ainsi modifiés ont toujours a fils, l’arbre est encore a-b.

• Si un nœud possède seulement a -1 fils, examiner ses frères adjacents.

– Si l'un de ces frères possède au moins a + 1 fils, il suffit de faire un partage avec ce frère.

– Sinon, les frères adjacents ont a fils, la fusion avec l'un

(37)

Exemples de suppression (1)

21 26 30

20 25 30 36

Suppression de 25

21 30

20 30 36 21

20 25

racine

20

(38)

Suppression de 12 (1)

Suppression de 12

11 6

20 8

21 26 30

4 7 10 12 21 25 30 36

(39)

Suppression de 12 (2)

L'arbre n'est plus 2-4

6

20 8

21 26 30

4 7 10 21 25 30 36

(40)

Suppression de 12 (3)

Après partage avec le frère droit.

20 6

21 8

26 30

4 7 10 21 25 30 36

(41)

Suppression de 13 (1)

11 6

20 8

21 4 7 10 13 21 25

Suppression de 13

(42)

Suppression de 13 (2)

6

20 8

21 4 7 10 21 25

L'arbre n'est plus 2-4

(43)

Suppression de 13 (3)

6

8

21

4 7 21 25

20 10

Après fusion avec le frère droit.

(44)

final

La déclaration d'une variable final doit toujours être accompagnée d'une initialisation.

Une méthode final ne peut être surchargée.

Une variable final ne peut être modifiée.

Attention ! Si la variable est un tableau, donc une référence, cette référence ne change plus, mais les valeurs du tableau peuvent être modifiées.

Une classe final ne peut pas avoir de classe dérivée.

Les méthodes d'une classe final sont implicitement

(45)

final

class Test {

static final int n = 100;

static final int[] a = {1, 2, 3};

public static void main(String args[]) {

a[0] = 5; // OK

n = 9; // Erreur ! Variable finale }

}

(46)

Spécial pub. La multiplication par 5

Cet automate réalise la multiplication par 5 en binaire inversé.

13 x 5 = 65 Entrée : 1011

Sortie : 1000001

(47)

Un petit casse-tête (1)

Un joueur a les yeux bandés. Face à lui, un plateau circulaire sur lequel sont disposés en carré quatre jetons, blancs d'un côté et noirs de l'autre. La configuration de départ est inconnue du joueur.

Le but du jeu est d'avoir les quatre jetons du côté blanc.

Configurations possibles, à une rotation près.

(48)

Règles du jeu

Le joueur peut retourner autant de jetons qu'il le souhaite, mais sans les déplacer. A chaque tour, le maître de jeu annonce si la configuration obtenue est gagnante ou pas, puis effectue une rotation du plateau de 0, 1, 2 ou 3 quarts de tours.

Peut-on gagner à coup sûr ? En combien de coups ?

(49)

La méthode toString (1)

Méthode de la classe java.lang.Object.

public String toString()

Elle retourne une chaîne de caractères formée par le nom de la classe, suivi de @, du codage du type puis de la référence

B byte J long

C char Lnom_de_classe classe

D double S short

F float Z boolean

I int

Précédé de [ dans le cas d'un tableau

(50)

La méthode toString (2)

public static void main(String args[]) {

byte[] T = {5, 2, 6};

System.out.println(T);

}

>[B@f96da1

[ --> Tableau B --> de bytes

@ --> Adresse, suivi de l'adresse en héxadécimal

(51)

La méthode toString (2)

Elle est parfois surchargée. Par exemple, dans java.lang.Class,

elle donne seulement le nom de la classe. Dans java.lang.String

elle retourne la chaîne de caractères.

public static void main(String[]args) { String p = "bonjour";

System.out.println(p);

} // affichera : bonjour

(52)

Les secrets de la classe String

• La classe String est final.

• Une chaîne de caractères renvoie toujours à la même instance de la classe String.

• Un tas de méthodes utiles :

int length()

int charAt(int index)

int compareTo(string s)

String replace(char c1, char c2) String toLowerCase()

String toUpperCase()

(53)

Autres méthodes utiles de la classe String

boolean startsWith(string prefix) boolean endsWith(string suffix) int indexOf(int ch, int from)

int indexOf(string facteur)

int lastIndexOf(int ch, int from) int lastIndexOf(string facteur) String substring(int i, int j)

int indexOf(int c, int fromIndex) int indexOf(string facteur)

String substring(int i, int j) String concat(string s), etc.

(54)

La classe String

class Test {

static final int[] a = {1, 2, 3};

static final int[] b = {1, 2, 3};

public static void main(String args[]) {

String s = "bonjour";

String t = "bonjour";

System.out.println(a == b); // false System.out.println(s == t); // true }

}

Références

Documents relatifs

Une interprétation ďune constante lui assigne un élément de ľunivers de discours ; ľinterpréta- tion ďun signe de relation lui assigne une relation dans cet univers ;

Les AVL sont d’abord des arbres de recherche, ils sont donc tels que tout nœud a une clé supérieure à celles des nœuds de son sous arbre gauche et inférieure à celles des nœuds

Note : Un parcours infixe d'un arbre binaire de recherche permet de traiter les clés de la plus petite à la plus grande pour un parcours infixe main gauche, ou de la plus grande à

Les AVL sont d’abord des arbres de recherche, ils sont donc tels que tout nœud a une clé supérieure à celles des nœuds de son sous arbre gauche et inférieure à celles des nœuds

L'insertion d'un élément peut produire un nœud ayant plus de b fils.. Amphi

Pour un dictionnaire de Scrabble TM anglais, la représentation par arbre digital nécessite 117 150 nœuds et 780 kilooctets de mémoire.. La théorie des automates

On peut modifier la visibilité des variables et des méthodes. Modificateur Visibilité private

pin noir, et même cèdre ou cyprès, sont ainsi délibérément sacri- fiés. Nous n'en discuterons pas le but; mais la joie des yeux nous paraît bien éphémère, si Ton considère