0% ont trouvé ce document utile (0 vote)
26 vues27 pages

6 ArbresRecherche

Transféré par

mahiguetconsulting
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
26 vues27 pages

6 ArbresRecherche

Transféré par

mahiguetconsulting
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

INF6

ALGORITHMIQUE
AVANCÉE
Manuele Kirsch Pinheiro
Carine Souveyet
05/03/16 2

Contenu prévisionnel
• Piles et files
• Listes
• Récursivité
• Récursivité dans le calcul
• Récursivité structurelle
• Arbres binaires
• Parcours en profondeur et en largeur
• Généralisation de la notion d’arbre
• Insertion et suppression de nœuds
• Arbre de recherche
• Recherche & manipulation
• Rééquilibrage
ARBRES DE RECHERCHE
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 4

Arbres binaires de recherche


( Binary Search Trees)
• Un arbre de recherche est un arbre binaire où les
nœuds sont organisés suivant une relation d’ordre
Soit a un arbre de recherche
∀a ∈ ArbreRecherche,
∀e ∈ SousArbreGauche(a) et ∀e’ ∈ SousArbreDroit(a)
alors
clé (e) ≤ clé ( racine (a) ) < clé (e’)

Toutes les valeurs de clé à 7


gauche de la racine sont Toutes les valeurs de clé à
inférieures à celle-ci droite de la racine sont
5 8 supérieures à celle-ci
clé (e) ≤ clé (racine)
clé (e’) > clé (racine)
2 6 9
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 5

Définitions
• Dans un arbre binaire de recherche :
• Toutes les clés du sous arbre gauche sont inférieurs ou égales
à la clé du nœud
• Toutes les clés du sous arbre droit sont strictement supérieurs
à la clé du nœud

Un parcours infixe dans l’arbre


permet d’obtenir l’ensemble de
valeurs ordonnées :
256789 n1 Le nœud n3 est à droite
de n1, il est donc
7 supérieur à celui-ci
n2 n3
5 8
n6 Le nœud n5 est à droite
Le nœud n4 est à 2 6 9 de n2 et à gauche de n1,
gauche de n2, il est il est donc supérieur n2 et
n4 n5
donc inférieur à celui-ci inférieur à n1
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 6

Définitions
• Un même ensemble de valeurs peut être
représenté par différents arbres, aux
profondeurs (height) distinctes

7 5
height

2 7

height
5 8
=2

=3
2 6 9 6 8

+ profondeur ⇒ - recherche efficace


05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 7

Opérations
• Différentes opérations peuvent être réalisées dans un
Arbre Binaire de Recherche (ABR)
• Opérations de recherche
• Search à recherche une valeur dans l’arbre
• Minimum à trouver la plus petite valeur contenue dans l’arbre
• Maximum à trouver la valeur maximale contenue dans l’arbre
• Successeur à trouver le prochain nœud (ou la prochaine valeur)
d’un nœud / valeur
• Prédécesseur à trouver le nœud (ou valeur) précédent un autre
• Opérations de manipulation
• Insertion à insérer une nouvelle valeur dans l’arbre
• Suppression à supprimer une valeur de l’arbre
• Rééquilibrage à rééquilibre l’arbre de manière à contrôler sa
profondeur
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 8

Opérations
Successeur
racine
de 13
15

6 18

maximum
3 7 17 20

minimum 2 4 13 Successeur
de 15
9
Prédécesseur
Prédécesseur de 15
de 13
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 9

Implémentations
• Différentes implémentations sont possibles
• avec ou sans la notion de nœud
• avec ou sans le parent
Visual Paradigm Professional Edition(Université Paris 1 Panthéon Sorbonne)

K
! Attention : l’absence d’un 0..1 -parent V

lien vers le parent a un fort -key : K


ABR

impact sur certaines opérations -value : V


sual Paradigm Professional Edition(Université Paris 1 Panthéon Sorbonne) -parent : ABR<K, V>
-left : ABR<K, V>
K
V 0..1 K extends Comparable -right : ABR<K, V>
-right +search(k : K) : ABR<K, V>
ABR
ê +min() : ABR<K, V>
-left afin de pouvoir comparer +max() : ABR<K, V>
0..1 les éléments (< ou >) +successor() : ABR<K, V>
+successor(key : K) : ABR<K, V>
+predecessor() : ABR<K, V>
K +predecessor(key : K) : ABR<K, V>
V +add(key : K, value : V)
Noeud +remove(key : K)
0..1 +reequilibrage()
-key : K
-value : V - l e f t 0..1 - r i g h t 0..1
-racine
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 10

Implémentations
• Avec parent et sans la notion de nœud

/
15 val

15

6 18

6 val 18 val
17
/ / /

17 val
/ /
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 11

Implémentations
• Sans parent et avec la notion de nœud

15 15 val

6 18

17

ABR
racine 6 val
18 val
/ /
Nœud /
key val
left right 17 val
/ /
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 12

Recherche dans un ABR


• Search
• Objectif : retrouver le nœud (sous-arbre) contenant
une certaine valeur K
• On dit que chaque nœud contient une valeur de clé qui
détermine son ordre dans l’arbre
• On cherche alors le nœud contenant la clé K
Search : Arbre x Key à Nœud
• Algorithme :
• On vérifie, pour chaque nœud x, s’il ne contient pas la valeur
de clé k recherchée. Si ce n’est pas le cas, on étend la
recherche aux sous arbres
• Si k < clé ( x ) alors le nœud recherché est à la sous arbre gauche
• Si k > clé ( x ) alors le nœud se trouve à la sous arbre droite
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 13

Recherche
• On recherche à partir d’un nœud x (this)
Search
Entrée :
ABR x Search ( n15, 13 )
Key k x n15
Sortie :
ABR y Search ( n6, 13 ) 15
n6 6 18
Si x == null OU k == x.key
Search ( n7, 13 )
alors n7
y=x 3 7 17 20
Sinon
Si k < x.key
alors y = Search ( x.left, k ) 2 4 13 y
sinon y = Search ( x.right, k) n13
fin si 9
fin si
retourner y Search ( n13, 13 )
fin
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 14

Recherche
• Ou de manière non récursive…

Search
Entrée : Search ( n15, 13 )
ABR x n15
Key k x
Sortie : 15
ABR y
n6 6 18
Tant que x ≠ null ET k ≠ x.key n7
faire 3 7 17 20
Si k < x.key
alors x = x.left
sinon x = x.right 2 4 13 y
fin si n13
fin tant 9
y=x
retourner y
fin
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 15

Min / Max
• Minimum
• La valeur minimale d’un ABR se trouve toujours à la
feuille à l’extrémité gauche de l’arbre.
• Pour la trouver, il suffit d’explorer le sous arbre gauche
à partir de la racine
• Maximum 15

• La valeur maximale se retrouve à 6 18


l’extrémité droite de l’arbre.
• Elle est donc accessible en 3 7 17 20

explorant le sous arbre droit


2 4 13
min max
9
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 16

Min / Max
• On recherche le min à partir de la racine (this)
Min n15.Min ()
Entrée : ≈
ABR racine Min ( n15 )
Sortie :
racine n15
ABR x
15
ABR x = racine
n6 6 18
Tant que x ≠ null ET x.left ≠ null
faire
n3
x = x.left 3 7 17 20
fin tant
n2
retourner x 2 4 13
fin
9
Exercice : on peut aussi le faire extrémité la
de manière récursive… plus à gauche
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 17

Min / Max
• On recherche le max à partir de la racine (this)
Max n15.Max ()
Entrée : ≈
ABR racine Max ( n15 )
Sortie :
racine n15
ABR x
15
ABR x = racine n18
Tant que x ≠ null ET x.right ≠ null 6 18
faire n20
x = x.right 3 7 17 20
fin tant

retourner x 2 4 13
fin
9 extrémité la
plus à droite
Exercice : on peut aussi le faire
de manière récursive…
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 18

Successeur / Prédécesseur
• Le successeur d’un nœud x est le nœud y
contenant la plus petite valeur supérieur à x
• Le prédécesseur d’un nœud x est le nœud y
contenant la plus grand valeur inférieur à x
Successeur de 13
15
Prédécesseur 6 18
de 7

… 7 17 …

13
Prédécesseur Le successeur de 15
de 15 …
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 19

Successeur / Prédécesseur
• Successeur : deux cas possibles
• x contient un sous arbre droit
• son successeur est le min de son sous arbre droit
(feuille à l’extrémité gauche de ce sous arbre)
• x ne contient pas de sous arbre droit
Le successeur de 15
• le successeur est un ascendant
est le min de son
• le + petit ancestral de x sous arbre droit
15

6 18

… 7 17 …

+ petit ascendant è le 1er ascendant Successeur de 13


13
dont la branche est à gauche (dans le est son + petit
sous arbre gauche de son parent) … ascendant
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 20

Successeur / Prédécesseur
• On recherche le successeur à partir d’un nœud x (this)
Successeur
Entrée :
ABR x Successeur ( n15 )
Sortie : x n15
ABR y
15
Si x ≠ null ET x.right ≠ null n6 6 18
alors
y = Min (x.right)
sinon 3 7 17 20
y = x.parent
Tant que y ≠ null ET x = y.right n13 13
2 4
faire
x=y min(n15.right)
y = y.parent x
fin tant Successeur ( n13 )
retourner y
fin
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 21

Successeur / Prédécesseur
• Prédécesseur : idem successeur, en inversant
droit et gauche
• x contient un sous arbre gauche
• son prédécesseur est le max de son sous arbre gauche
(feuille à l’extrémité droit de ce sous arbre)
• x ne contient pas de sous arbre gauche
• le prédécesseur est
15
un ascendant
• le 1er ancestral de x 6 18
appartenant au sous arbre
droit de son parent … 7 17 …

Prédécesseur de 17 est
13 son + grand ascendant
Le prédécesseur de 15 est le (celui à la sous arbre
max de son sous arbre gauche …
droit de son père)
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 22

Successeur / Prédécesseur
• On recherche le successeur à partir d’un nœud x (this)
Prédécesseur
Entrée :
ABR x Prédécesseur ( n15 )
Sortie : x n15
ABR y
15
Si x ≠ null ET x.left ≠ null n6 6 18
alors
y = Max (x.left)
sinon 3 7 17 20
y = x.parent
Tant que y ≠ null ET x = y.leftt n13 13
2 4 x
faire
x=y Prédécesseur
y = y.parent max(n15.left)
( n17 )
fin tant
retourner y
fin
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 23

Successeur / Prédécesseur
• On peut également demander le successeur ou
prédécesseur d’une valeur de clé
(et pas d’un nœud) Visual Paradigm Professional Edition(Université Paris 1 Panthéon Sorbonne)

• successor() à successeur d’un nœud


K
0..1 -parent V

(au vu de sa clé)
ABR
-key : K
-value : V

• successor(key: K) à successeur -parent : ABR<K, V>


-left : ABR<K, V>

d’une valeur de clé à partir de la racine -right : ABR<K, V>


+search(k : K) : ABR<K, V>
+min() : ABR<K, V>
+max() : ABR<K, V>
+successor() : ABR<K, V>

• Attention : +successor(key : K) : ABR<K, V>


+predecessor() : ABR<K, V>
+predecessor(key : K) : ABR<K, V>
• lors qu’on n’a pas le parent, +add(key : K, value : V)
+remove(key : K)
successor () considère le nœud +reequilibrage()
- l e f t 0..1 - r i g h t 0..1

comme racine (impossible de


remonter l’arbre au-delà de ce nœud)
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 24

Successeur
Entrée :
il faut d’abord trouver
le nœud contenant la
Successeur
Key k valeur recherchée • On recherche le
ABR racine (ou la plus proche
Sortie : successeur à partir d’un
dans l’arbre)
ABR a nœud racine (this)
Si racine.key ≠ null Alors Successeur ( n15 , 13 )
Si k < racine.key Alors Successeur ( n15 , 19 )
Si racine.left ≠ null Alors
a = successeur (k, racine.left) racine n15 Successeur
sinon a = racine 15 ( n18 , 19 )
fin Si Successeur
Sinon Si k > racile.key Alors ( n6 , 13 ) 6 n6 n18 18
Si racine.right ≠ null Alors
n7
a = successeur (k, racine.right) … … n20 20
Sinon a = successeur (racine) 7
Successeur
Fin si ( n7 , 13 ) Successeur
Sinon a = successeur (racine) n13 13
( n20 , 19 )
fin Si Successeur
Sinon a = null (ou exception car arbre vide) ( n13 , 13 )
retourner a Successeur ( n13 )
fin
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 25

Successeur / Prédécesseur
• Si on simplifie la structure de données en supprimant le
pointeur vers le parent :
• On ne peut plus remonter l’arbre à appel à partir de la racine
• On aura besoin de garder une « trace » des appels pour retrouver
les parents
• Structure auxiliaire : une pile
Méthode public
ê
public ABR successeur (K key ) créer la pile et lancer la méthode
interne (protected)
Si this.key == null Alors
retourner null (ou lancer exception) Méthode protected
ê
Pile p = nouvelle Pile ABR successeur ( K key , Pile p )
retourner this.successeur ( key, p ) parcours l’arbre de manière
récursive à la recherche du
fin successeur
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 26

Successeur / Prédécesseur
• Successeur ( clé ) sans parent
protected ABR successeur ( K key , Pile p )

Si key < this.key Alors Sinon


Si this.left ≠ null Alors Si this.right ≠ null Alors
p.empile ( this ) retourner this.right.min ()
retourner left.successeur ( key, p ) Sinon
sinon ABR x = this
retourner this Tant que ! p.estVide() Faire
fin Si ABR pere = p.depiler ()
Sinon Si key > this.key Alors Si x ≠ pere.right Alors
Si this.right ≠ null Alors retourner pere
p.empile ( this ) Sinon
retourner right.successeur ( k, p ) x = pere
Sinon fin Tant
retourner successeur ( this.key , p ) retourner null
Fin si fin Si
… fin Si on ne l’a pas trouvé
fin dans l’arbre…
05/03/16 Manuele Kirsch Pinheiro - CRI/UP1 - [email protected] 27

Successeur / Prédécesseur
• Successeur ( clé ) sans parent racine
n15.successeur (13 ) 15
n15
6 18
n15.successeur (13 , [ ]) n6
this = n15 p = [ n15 ]
8 17
n8
n6.Successeur ( 13 , [ n15 ] )
this = n6 p = [ n6 , n15 ] 7 13
n13

n8.Successeur ( 13 , [n6 , n15 ] )


this = n8 p = [ n8 , n6 , n15 ] x = n13 p = [ n8 , n6 , n15 ]
pere = n8
x = n8 p = [ n8 , n6 , n15 ]
pere = n6
n13.Successeur ( 13 , [ n8 , n6 , n15 ] ) x = n6 p = [ n8 , n6 , n15 ]
this = n13 p = [ n8 , n6 , n15 ] pere = n15

Vous aimerez peut-être aussi