CHAPITRE3

Télécharger au format pdf ou txt
Télécharger au format pdf ou txt
Vous êtes sur la page 1sur 36

Algorithmiques et complexité

Deuxième année Ingénieur


Dr.BOUHATEM FARIZA
Maître de Conférences B
Département d'Informatique
FGEI
2023 /2024
Table des matières

I - Chapitre 3 : Les Arbres 3


1. Rappels d'arbres ........................................................................................................4
1.1. Qu'est ce qu'un arbre ? .....................................................................................................................4

2. Arbres binaires ...........................................................................................................5


2.1. C'est quoi un arbre binaire ? .............................................................................................................5
2.2. Arbre binaire particuliers ..................................................................................................................6
2.3. Parcours d'arbres binaires ................................................................................................................8
2.4. Opérations sur l'arbre binaire de recherche ..................................................................................11

3. Représentation et implémentation.........................................................................14
3.1. Arbre binaire de recherche .............................................................................................................14
3.2. Arbre binaire de recherche équilibré AVL( Adelson-Velskii et Landis) ..........................................15
3.3. Arbre général ...................................................................................................................................20

4. Structure de données "Tas" ....................................................................................31


4.1. C'est quoi un tas ?............................................................................................................................31
4.2. Implémentation d'un tas ................................................................................................................32
4.3. Opérations sur les tas ......................................................................................................................33
4.4. Tri par tas (Heapsort) ......................................................................................................................34

2
Chapitre 3 : Les Arbres I

En informatique , le stockage de données volumineuses nécessite l'utilisation des structures de


données permettant un accès efficace aux informations.
Les informations sont souvent hiérarchisées, et peuvent être représentées sous forme
arborescente.
Les arbres sont les structures de données hiérarchiques les plus répondues en informatique
permettant de représenter plusieurs types de problèmes.
Les systèmes de fichiers, les arbres généalogiques, les structures organisationnelles et d'autres
sont tous représentés par des arbres et les figures suivantes illustrent deux exemples.

Organisation du système de fichier (sur le disque dur d'un ordinateur)

Exemple d'arborescence d'un site web

3
Chapitre 3 : Les Arbres

1. Rappels d'arbres
1.1. Qu'est ce qu'un arbre ?
Un arbre est une structure de données hiérarchique qui est composée de nœuds reliés par des arêtes. il
ressemble à un arbre réel avec des branches et des feuilles. Dans une structure de données
arborescente, il existe un nœud unique appelé Racine, qui sert de point de départ. Chaque nœud de
l'arbre peut avoir zéro au plusieurs nœuds Enfants, formant ainsi une structure en branches.

Terminologie des arbres Complément

1. Racine : Le nœud le plus élevés dans un arbre. Il sert de point de départ pour parcourir l'arbre.
2. Enfant : Un nœud directement connecté à un autre nœud en sʼéloignant de la racine.
3. Parent : L'inverse d'un enfant . Un nœud est le parent de ses nœuds enfants.
4. Frère ou sœur : Des nœuds qui partagent le même père.
5. Feuille : Un nœud qui n'a pas d'enfants.

Un arbre
Les nœuds internes dans la figure peuvent être des parents, enfants et des frères ou sœurs

Notions sur les arbres Fondamental

• La racine est de niveau 1. Certains auteurs affectent le niveau 0 à la racine.


• Le degré d'un nœud est égal au nombre de ses nœuds fils.
• Le degré d'un arbre est égal au plus grand des degrés de ses nœuds.
• La taille d'un arbre est égale au nombre total de ses nœuds.
• La hauteur d'un arbre est le nombre de nœuds du chemin le plus long dans l'arbre.
• La hauteur de l'arbre vide est égale à 0.

4
Chapitre 3 : Les Arbres

2. Arbres binaires
2.1. C'est quoi un arbre binaire ?

Définition

Un arbre binaire est un arbre de degré 2 ou chaque nœuds a au plus deux fils. Le premier fils est
appelé Fils -Gauche (FG) et le deuxième fils est appelé Fils-Droit (FG).
Par exemple sur la figure ci-dessous, le nœud A possède deux sous-arbres : : sous-arbre gauche et sous-
arbre droit.

Arbre binaire Exemple

Arbre binaire

Remarque

Les arbres binaires sont utilisés pour traiter des données. Chaque nœud peut donc être représenté par
la donnée qu'il contient. Ainsi, dans l'arbre de l'exemple , la donnée contient des caractères (A à J).

Compte tenu de la nature récursive d'un arbre, la représentation la plus couramment utilisée est celle
chaînée dont le principe est de désigner un arbre binaire par un ensemble de cellules mémoire à trois
champs :

FG Val FD

- FG est un pointeur vers le sous arbre gauche.


- Val représente l'information apportée par le nœud pour un arbre étiqueté.
- FD est un pointeur vers le sous arbre droit.
- L'accès à un arbre est donc déterminé par l'adresse (pointeur) de sa racine.
Nous avons alors la déclaration suivante :
1 Type arbre_binaire= ^noeud
2 noeud= structure
3 Val: élement;
4 FG, FD: arbre_binaire;
5 finstructure
6
7 Variables
8 A: arbre_binaire;

5
Chapitre 3 : Les Arbres

Représentation chaînée d'un arbre A

Remarque

- Arbre A est vide : A = NIL.


- Accès à l'élément (étiquette) du nœud A : A↑val.
- Accès au sous-arbre gauche de A : A↑FG.
- Accès au sous-arbre droit de A : A↑FD.

2.2. Arbre binaire particuliers

Arbre binaire parfait Définition

Un arbre binaire parfait est un arbre dans lequel chaque niveau est complètement rempli, à l'exception
éventuelle du dernier niveau, qui est rempli de gauche à droite. Cependant, si le dernier niveau n'est
pas complètement rempli, les nœuds présents sont regroupés à gauche de l'arbre.

Arbre binaire dégénéré Définition

Un arbre binaire est dégénéré si chacun de ses nœuds internes n'a qu'un seul descendant ( gauche ou
droit). Un arbre binaire dégénéré est un arbre formé uniquement de points simples: c'est une liste.

6
Chapitre 3 : Les Arbres

Arbre binaire complet Définition

Un arbre binaire est complet lorsque son nombre de nœuds est 2H-1 où H est sa hauteur.

Arbre binaire de recherche Définition

Un arbre binaire de recherche est une structure de données qui permet de représenter un ensemble de
clés si l'on dispose d'une relation d'ordre sur ces clés. Autrement dit chaque nœud possède une valeur
plus grande que tous les nœuds qui forment son sous-arbre gauche et plus petit que tous les nœuds
qui forment son sous arbre droit. Autrement dit, un arbre binaire de recherche (ABR) est un arbre
binaire ordonné tq : FG (x) < x < FD (x). On peut aussi imaginer la relation inverse, i.e. FG (x) > x > FD (x).

Arbre binaire de recherche équilibré AVL Définition

Un ABR est dit équilibré si pour tout nœud y de l'arbre on a :


| FE(y) | <= 1.
- Un facteur d'équilibre FE d'un noeud y est défini comme étant la différence entre la hauteur du sous-
arbre droit et celle du sous-arbre gauche. On le note comme suit :
FE (y) = h ( FG(y)) - h (FD (x)) ou FE (y) = h (FD (y)) - h (FG(y)) avec h (FD (y)) est la hauteur du fils droit de y
et h(FG(y)) est la hauteur du fils gauche de y.
Propriété : Si n est le nombre de nœuds d'un arbre AVL alors sa hauteur est log2(n)

7
Chapitre 3 : Les Arbres

2.3. Parcours d'arbres binaires


Pour utiliser un arbre, il faut le parcourir. Or, il existe plusieurs ordres de parcours qui tous ont un intérêt
différent. dans ce chapitre nous allons étudié le parcours en profondeur et le parcours en largeur.
a) Parcours en profondeur (DFS ou Depth-First Search)
Les parcours en profondeur sont des parcours qui seront traités de manière récursives, en partant de la
racine. Les trois parcours en profondeur bien connus et couramment utilisés dans le cadre des arbres
binaires sont :
Le parcours préfixe (préordre) : On commence de la Racine puis on passe aux Fils Gauches et
enfin on termine par les Fils Droits (R,FG,FD).
Le parcours infixe (inordre) : On commence de Fils Gauches puis on passe à la Racine et enfin
on termine par les Fils Droits (FG,R,FD).
Le parcours suffixe (postordre, postfixe) : On commence de Fils Gauches puis on passe aux Fils
Droits et enfin on termine par la Racine (FG,FD,R).

8
Chapitre 3 : Les Arbres

Exemple d'un parcours préfixe Exemple

L'ordre d'affichage des nœuds est donc : : 1, 2, 4, 5, 8, 9, 3, 6, 10, 7, 11

Exemple d'un parcours infixe Exemple

L'ordre d'affichage des nœuds est donc : 4, 2, 8, 5, 9, 1, 10, 6, 3, 7, 11

Exemple d'un parcours suffixe Exemple

L'ordre d'affichage des nœuds est donc : 4, 8, 9, 5, 2, 10, 6, 11, 7, 3, 1

9
Chapitre 3 : Les Arbres

Les algorithmes récursifs de parcours d'arbres binaires


Parcours préfixe
1 procédure préfix (b : arbre_binaire) ;
2 Si (b <> NIL) Alors
3 ecrire (b↑.Val) ;
4 prefix (b↑.FG) ;
5 prefix (b↑.FD)
6 Fin Si

Parcours infixe
1 procédure infix (b : arbre_binaire) ;
2 Si (b <> NIL) Alors
3 infix (b↑.FG) ;
4 ecrire (b↑.Val) ;
5 infix (b↑.FD)
6 Fin Si

Parcours suffixe
1 procédure suffix (b : arbre_binaire) ;
2 Si (b <> NIL) Alors
3 suffix (b↑.FG) ;
4 suffix (b↑.FD);
5 ecrire (b↑.Val) ;
6 Fin Si

b) Parcours en largeur (BFS ou Breadth-First Search)


Pour ce type de parcours on ne peut pas appliquer la récursivité, car l'arbre n'obéit plus à une
définition récursive, mais il est considéré comme étant formés de niveaux, chaque niveau contenant un
certain nombre de nœuds.
Le parcours en largeur d'un arbre consiste à parcourir chaque niveau de l'arbre de gauche à droite, en
partant de la racine. Le parcours en largeur de l'arbre ci-dessous est : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11.

L'algorithme de parcours en largeur


Voici les étapes de l'algorithme de parcours en largeur :
1. Mettre le nœud racine dans la file.
2. Retirer le nœud du début de la file pour le traiter.
3. Mettre tous ses voisins non éplorés dans la file(à la fin).
4. Si la file n'est pas vide reprendre à l'étape 2.

10
Chapitre 3 : Les Arbres

1 Procédure Parcours_Largeur (A: arbre_binaire);


2 Debut
3 file<- filevide;
4 enfiler(Racine(A),file);
5 Tant que (file<> NIL) faire
6 noeud<- defiler(file);
7 afficher(noeud);
8 Si(FG(noeud)<> NIL) alors
9 enfiler(FG(noeud),file);
10 Si (FD(noeud)<> NIL) alors
11 enfiler(FD(noeud), file);
12 ftq
13 Fin

2.4. Opérations sur l'arbre binaire de recherche


a) Recherche d'un élément
Principe
La recherche d'un élément (une valeur) dans un ABR consiste, en partant de la racine, à parcourir une
branche en descendant chaque fois sur le fils gauche ou sur le fils droit selon que la clé portée par le
nœud est plus grande ou plus petite que la valeur cherchée. La recherche sʼarrête dés que la valeur est
rencontrée ou que l'on a atteint lʼextrémité d'une branche (le fils sur lequel il aurait fallu descendre
n'existe pas).

Recherche de la valeur 27 Exemple

b) Insertion d'un élément


Principe
Lʼélément inséré est toujours une feuille. Dans l'exemple ci-dessous lʼélément à insérer est 31.

11
Chapitre 3 : Les Arbres

Insertion de la valeur 31 dans l'arbre Exemple

c) Suppression d'un élément


Principe
Lʼopération de suppression dépend du nombre de fils du nœud à supprimer dans l'ABR. Les différents
cas de figure possibles sont les suivants :
-cas de suppression d'une feuille.
- cas de suppression d'un nœud ayant un seul fils.
- cas de suppression d'un nœud ayant deux fils.

Cas d'une feuille


Le nœud à supprimer n'a pas de fils : on lʼélimine simplement de l'arbre en modifiant le lien de son
père. Si le père n'existe pas, l'arbre devient l'arbre vide.

Suppression de la valeur 51 Exemple

Cas d'un seul fils


Le nœud à supprimer a un unique fils : on détache le nœud et on relie directement son père et son fils.
Si ce père n'existe pas, l'arbre est réduit au fils unique du nœud supprimé.

12
Chapitre 3 : Les Arbres

Suppression de la valeur 55 Exemple

Cas de deux fils


Le nœud à supprimer a deux fils :
1. Rechercher le plus petit descendant du sous-arbre droit, soit p
2 Remplacer la valeur du nœud à supprimer par la valeur de p.
3. Remplacer p par FD (p)
ou bien :
1. Rechercher le plus grand descendant du sous-arbre gauche, soit p.
2. Remplacer la valeur du nœud à supprimer par la valeur de p.
3. Remplacer p par FG (p)

Suppression de la valeur 76 Exemple

Dans l'exemple, le plus grand descendant gauche est 73 , alors remplacer 76 par 73 et remplacer 73 par
son fils gauche qui est le sous arbre qui contient les nœuds 72,71

13
Chapitre 3 : Les Arbres

3. Représentation et implémentation
3.1. Arbre binaire de recherche
Un arbre binaire de recherche peut être représenté de différentes manières en utilisant une structure
de données dynamique ou une structure de données statique.
1. Représentation statique
Il existe deux catégories de représentations internes statiques : la représentation statique standard et
la représentation statique séquentielle.
-Le modèle statique standard permet de représenter explicitement les nœuds fils comme sur la figure
ci-dessous :

-Le modèle statique séquentiel permet de représenter implicitement les nœuds fils. Le nœud à la
position P est le père implicite des nœuds aux positions 2P et 2P+1.

2. Représentation dynamique
Dans la représentation dynamique d'un arbre binaire chaque nœud possède deux pointeurs : un vers le
sous arbre gauche et un autre vers le sous arbre droit. L'arbre est déterminé par l'adresse de sa racine.
Cette représentation est réalisée par les listes chaînées.
La représentation mémoire de l'arbre abstrait de l'expression a * (c + d) par une liste chaînée non
linéaire est illustrée par la figure suivante :

14
Chapitre 3 : Les Arbres

3.2. Arbre binaire de recherche équilibré AVL( Adelson-Velskii et Landis)


Dans un arbre binaire de recherche équilibré, pour chaque nœud de l'arbre, la différence de
hauteur de ses sous-arbres est au maximum un. Voici quelques exemples (où apparaît la
différence de profondeur des sous-arbres de chacun des nœuds) :

Arbres AVL
Les valeurs autorisées de facteur d'équilibre (BF) sont –1, 0 et +1.
-La valeur –1 indique que le sous-arbre de droite en contient un supplémentaire, c'est-à-dire que
l'arbre est lourd à droite.
-La valeur +1 indique que le sous-arbre de gauche contient un extra, c'est-à-dire que l'arbre est laissé
lourd.
-La valeur 0 montre que l'arbre comprend des nœuds égaux de chaque côté, c'est à dire que l'arbre est
parfaitement équilibré.
La représentation d'un arbre binaire équilibré suit généralement les mêmes représentation d'un
arbre binaire (représentation statique et dynamique).

Recherche, ajout et suppression d'un élément dans un AVL


1- Recherche d'un élément :
Le principe de la recherche dans un AVL est le même que dans un ABR.
L'intérêt d'un arbre AVL se situe dans la recherche. En effet, puisque l'arbre est équilibré, on évite
d'avoir des situations où la recherche est spécialement longue (comme c'est le cas dans
l'arbre binaire de recherche suivant si on cherche « f ») :

Arbre binaire non équilibré


2- Ajout d'un élément : L'insertion d'un nœud se fait exactement comme dans un arbre binaire .
Cependant, suite à chaque ajout, on remonte du nouveau nœud jusqu'à la racine de l'arbre en
calculant la différence de profondeur des sous-arbres de chacun des nœud rencontrés. Si cette
différence est égale à deux ou moins deux, on rééquilibre avec la bonne rotation.

15
Chapitre 3 : Les Arbres

ROTATION SIMPLE GAUCHE (LL : single Le rotation)


Cas où le nœud a une différence de profondeur des sous-arbres de 2 et le fils droit une différence
de 1.

ROTATION SIMPLE DROITE (RR : single Right rotation)


Cas où le nœud a une différence de profondeur des sous-arbres de -2 et le fils gauche une
différence de -1.

ROTATION DOUBLE DROITE GAUCHE (RL : Right Le rotation)


Cas où le nœud a une différence de profondeur des sous-arbres de 2 et le fils droit une différence
de -1.

ROTATION DOUBLE GAUCHE DROITE (LR :Le Right rotation)


Cas où le nœud a une différence de profondeur des sous-arbres de -2 et le fils gauche une
différence de 1.

16
Chapitre 3 : Les Arbres

Insertion de 10, 5, 6, 12, 14, 8 dans un AVL Exemple

Ajout de la valeur 10 : comme racine

Ajout de la valeur 5 comme fils gauche de 1O.

Ajout de la valeur 6 : comme fils gauche de 10 et fils droit de 5.

Cas de –2, 1 : Rotation double gauche droite dʼoù les rotations suivantes :

Ajout de la valeur 12 : comme fils droit de 6 et fils droit de 10 ;

17
Chapitre 3 : Les Arbres

Ajout de la valeur 14 :comme fils droit de 6 et fils droit de 10 et fils droit de 12.

Cas 2, 1 : Rotation simple gauche

Ajout de la valeur 8 : comme fils droit de 6 et fils gauche de 12 et fils gauche de 10.

Cas 2, -1 : Rotation double droite gauche

18
Chapitre 3 : Les Arbres

3- Suppression d'un élément : La suppression est également très simple. Nous supprimons en
utilisant la même logique que dans les arbres binaires de recherche. Après suppression, nous
restructurons l'arbre, si nécessaire, pour conserver sa hauteur équilibrée.
Étape 1: Trouvez l'élément dans l'arborescence.
Étape 2: Supprimez le nœud, conformément à la suppression dans un arbre binaire de recherche.
Étape 3: Deux cas sont possibles :
Cas 1: SUPPRESSION DE SOUS-ARBRE DROIT :
1A. Si BF(node) = +2 et BF(node -> le -child) = +1, effectuez une rotation RR( rotation droite).
1B. Si BF(node) = +2 et BF(node -> le -child) = -1, effectuez une rotation LR (double rotation gauche-
droite).
1C. Si BF(node) = +2 et BF(node -> le -child) = 0, effectuez une rotation RR (rotation droite)

Cas 2: SUPPRESSION DE SOUS-ARBRE GAUCHE :


2A. Si BF(node) = -2 et BF(node -> right-child) = -1, effectuez une rotation LL (rotation gauche).
2B. Si BF(node) = -2 et BF(node -> right-child) = +1, effectuez une rotation RL (double rotation droite-
gauche).
2C. Si BF(node) = -2 et BF(node -> right-child) = 0, effectuez une rotation LL (rotation gauche)

19
Chapitre 3 : Les Arbres

3.3. Arbre général


Contrairement à un arbre binaire, un arbre général permet à un nœud d'avoir un nombre arbitraire
d'enfants. Chaque nœuds peut avoir un degré quelconque c'est à dire un nombre variable d'enfants
comme dans la figure ci-dessous le nœud A possède 3 fils tant dit que le nœud D possède 4 fils.

20
Chapitre 3 : Les Arbres

3.3.1 Parcours
Les parcours les plus communément utilisés sont :
Parcours infixe : consiste à visiter le sous_arbre gauche, puis la racine et enfin le sous arbres droit : T1,
Racine ,T2 ... Tn
Parcours préfixe: consiste à visiter la racine , puis le sous_arbre de gauche à droite : Racine,T1 T2 ... Tn
Parcours suffixe: consiste à visiter le le sous_arbre de gauche à droite puis la racine :T1 T2 ... Tn, Racine

Les trois parcours de l'arbre de la figure ci-dessus donnent respectivement :


Infixe: b a d c f e k
Préfixe : a b c d f e k
Suffixe: b d f c k e a

3.3.2 Représentation et manipulation d'un arbre général


La manipulation d'un arbre général en machine nécessite qu'il soit implémenté sous forme d'un arbre
binaire qui est généralement plus facile à manipuler. Ainsi, dans ce qui suit, on montre comment on
peut passer d'un arbre général à un arbre binaire. La transformation d'un arbre général à un arbre
binaire passe par les deux étapes suivantes :
Lier les nœuds frères dans une liste linéaire chaînée.

Rotation de 45° dans le sens des aiguilles d'une montre.


A- Transformation de l'arbre général suivant en un arbre binaire :

B- Liaison des nœuds frères dans une liste linéaire chaînée (les liens en rouge ) .

21
Chapitre 3 : Les Arbres

C- Rotation de 45° dans le sens des aiguillés d'une montre.

Il existe nombreuses façon de représenter un arbre général en mémoire :


1- Représentation statique standard : On peut utiliser la représentation statique standard; mais, le
tableau représentatif risque dʼêtre creux (perte d'espace) comme c'est le cas avec la figure suivante :

22
Chapitre 3 : Les Arbres

2- Représentation par un tableau et une liste : On peut remédier à la perte d'espace engendrée par la
représentation statique standard en adoptant un autre modèle de représentation. On utilise, à cet effet,
un tableau de nœuds (statique). Ensuite, à chaque nœud est associée la liste de ses fils (dynamique).
C'est la représentation semi statique ou semi dynamique.

3- Représentation statique dense : On peut également adopter une autre représentation nommée
représentation statique dense dite aussi représentation par index_parent comme illustré par la table
de la figure ci-après :

4- Représentation dynamique par une liste chaînée : on peut représenter l'arbre général de manière
purement dynamique par une liste chaînée après l'avoir transformé en un arbre binaire. Ci-après le
modèle de représentation :

5- Représentation sous forme d'une matrice d'adjacence : Dans une représentation en matrice
d'adjacence, chaque nœud de l'arbre est représenté par une ligne de la matrice. La colonne i de la ligne
j indique si le nœud j est un enfant du nœud i.

23
Chapitre 3 : Les Arbres

Remarque

La représentation d'un arbre général en mémoire est choisie en fonction de l'application. Par exemple
une liste chaînée est une bonne représentation pour un arbre général dans lequel l'ordre des nœuds
n'est pas important. Un arbre binaire est une bonne représentation pour un arbre général dans lequel
chaque nœud a au plus deux enfants. Une matrice d'adjacence est une bonne représentation pour les
arbres généraux dans lesquels l'ordre des nœuds est important.

L'implémentation d'un arbre général adoptant la représentation dynamique "liste chaînée" est donnée
par le pseudo-code suivant :
1 type arbre_général =^ noeud
2 noeud= structure
3 Val: élément;// stocke la valeur du noeud
4 enfant:arbre_général;// enfant:pointe vers le premier enfant du noeud (s'il en a)
5 frére_suivant: arbre_général;//frére_suivant:pointe vers le noeud suivant
6 // de méme niveau
7 finstructure
8
9 Variables A:arbre_général;
10

24
Chapitre 3 : Les Arbres

Fonction créer_ nœud ()


1 Fonction créer_nœud(Valeur:élément):arbre_général;
2 var nouveau_noeud:arbre_général;
3 Début
4
5 New (nouveau_noeud);
6 nouveau_noeud↑.Val <- Valeur;
7 nouveau_noeud↑.enfant <- NIL;
8 nouveau_noeud↑.frére_suivant <- NIL;
9 créer_nœud <- nouveau_noeud;
10
11 Fin

Procédure Ajout_enfant ()
1 Procedure Ajout_enfant (var parent, enf: arbre_général);
2 var noeud_courant: arbre_général;
3 Début
4
5 Si parent↑.enfant= NIL alors // cas d'ajout du premier enfant à un noeud parent
6 parent↑.enfant <- enf // pointer vers le noeud enfant
7
8 Sinon //cas d'ajout du deuxiéme enfant au meme parent
9 début
10
11 noeud_courant <- parent↑.enfant;// noeud_courant est un pointeur de type
12 // arbre_général
13 Tant que noeud_courant↑.frére_suivant <> NIL faire // ceci est executé si par
14 // exemple un noeud contient
15 // plus de deux enfants
16 noeud_courant <- noeud_courant↑.frére_suivant;
17 Ftq;
18
19 noeud_courant↑.frére_suivant <- enf; //relier l'enfant a son frére_suivant
20 finSinon
21 finsi
22 Fin

Implémentation de l'arbre général A en utilisant le pseudo-code en haut Exemple

Arbre général A

25
Chapitre 3 : Les Arbres

Ici nous avons :


- la racine qui est le nœud "1".
- L'enfant 1 qui est le nœud "2".
- L'enfant 2 qui est le nœud "3".
- Lʼenfant 3 qui est le nœud "5".
- L'enfant 4 qui est le nœud "4".
Dʼoù :
-racine <- créer_nœud ('1') ;
-enfant1<- créer_nœud ('2') ;
-enfant2 <- créer_nœud ('3') ;
-enfant3 <- créer_nœud ('5') ;
Dʼoù le résultat suivant :

-Ajout_enfant (racine, enfant1) ;c-à-d : Ajout_enfant (1, 2) exécution de si: (1↑. enfant <- 2),comme la
montre la figure suivante :

-Ajout_enfant (racine, enfant2) ;c-à-d : Ajout_enfant (1, 3) , exécution de sinon, nœud_courant <- 1↑.
enfant=2 et 2↑. frère_suivant<- 3 ; comme la montre la figure suivante :

26
Chapitre 3 : Les Arbres

-Ajout_enfant (racine, enfant3) ;c-à-d : Ajout-enfant (1,5), exécution de sinon, nœud_courant <- 1↑.
enfant=2,exécution de la boucle tant que car 2↑. frère_suivant= 3<> Nil : nœud_courant pointe vers
3, on sort de la boucle tant que. 3↑. frère_suivant<- 5. Comme est illustré dans la figure suivante :

-enfant4 <- créer_nœud ('4') ;

-Ajout_enfant (enfant1, enfant4) ;c-à-d Ajout(2,4),exécution de si, 2↑. enfant<-4. Comme la montre la
figure suivante :

3.3.3 Recherche, suppression et ajout d'un élément dans un arbre général


1-Recherche d'un élément : Le principe de la recherche d'un élément dans arbre général ce fait
comme suit :
Commencer à la racine : La recherche commence généralement à la racine de l'arbre.
Parcourir les nœuds : en profondeur ou en largeur.
comparez les valeurs : A chaque nœud, comparez la valeur du nœud en cours avec la valeur
recherchée.
Répéter le processus : Répétez le processus pour les enfants (ou les frères) jusquʼà ce que tout
l'arbre soit parcouru ou jusquʼà ce que le nœud soit trouvé.

27
Chapitre 3 : Les Arbres

Recherche du nœud "G" (parcours en profondeur) Exemple

2- Suppression d'un élément : Le principe de la suppression d'un élément dans un arbre général est le
suivant :
Rechercher lʼélément à supprimer afin de le localiser dans l'arbre.
Gérer les liens parentaux.
Gérer les liens enfants.
Libérer la mémoire.
Cas d'une feuille : Si la feuille contient des frères le nœud parent garde les relations avec les frères de
la feuille sinon il pointe vers NIL.

28
Chapitre 3 : Les Arbres

Suppression de "G" Exemple

Cas d'un nœud interne : les enfants du nœud interne deviennent les enfants du nœud parent.

Suppression de "B" Exemple

29
Chapitre 3 : Les Arbres

3-Ajout d'un élément : Le principe de l'ajout d'un nœud dans un arbre général est le suivant :
Localisation du nœud parent : identifier le nœud existant auquel le nouveau nœud sera rattaché
(recherche du nœud parent).
Création du nouveau nœud.
Attachement du nouveau nœud au nœud parent.
Mettre à jour les références entre les nœuds.

Ajout du nœud "K" comme enfant du nœud "C" . Exemple

3.3.4 Tableau récapitulatif des complexités des opérations d'insertion,


Complément
suppression et recherche d'un élément dans un ABR , AVL et arbre général

Arbre Binaire de Arbre Binaire de


Opérations /Arbres Arbre Général
Recherche Recherche Équilibré AVL

-En moyenne : O(log n)


-O(n) : dans le pire des
-Au pire : O(n)(cas d'un - O(log n) dans tous les
cas car il nʼy a pas de
Recherche arbre dégénéré) cas, car l'arbre est
garantie sur la
avec n est le nombre de toujours équilibré
structure de l'arbre.
nœuds de l'arbre

- O(log n) dans tous les


-En moyenne : O(log n) cas, car les rotations
Ajout - Au pire : O(n)
-Au pire : O(n) d'équilibrage sont
effectuées

-En moyenne : O(log n) - O(log n) dans tous les


Suppression cas, car les rotations - Au pire : O(n)
-Au pire : O(n) maintiennent l'équilibre

30
Chapitre 3 : Les Arbres

En résumé, les arbres AVL garantissent un équilibre qui maintient la complexité à O(log n) pour les
opérations de base, tandis qu'un arbre binaire de recherche ordinaire peut dégénérer dans le pire des
cas. Les arbres généraux n'ont généralement pas de propriétés d'équilibre, ce qui peut conduire à des
performances moins prévisibles.

4. Structure de données "Tas"


Les tas en informatique, sont utilisés pour résoudre efficacement plusieurs problèmes courants liés à la
gestion des données tels que:
1-Implémentation des files de priorité : les éléments avec la priorité la plus élevée(ou la plus basse) sont
traités en premier.
2-Tri par tas : trier un ensemble dʼéléments de manière efficace en les insérant dans un tas, puis en
retirant successivement l'élément racine.

4.1. C'est quoi un tas ?

Définition

Un tas (heap en anglais) est un arbre qui vérifie les deux propriétés suivantes :
1. C'est un arbre binaire parfait c'est-à-dire un arbre binaire dont tous les niveaux sont remplis sauf
éventuellement le dernier où les éléments sont rangés le plus à gauche possible.
2. il est ordonné en tas :On dit qu'un arbre est ordonné en tas lorsque la propriété suivante est vérifiée :
les nœuds sont ordonnés par leurs clés respectives,
On parle d'un tas-max (Max-heap) si tout nœud a une valeur plus grande ou égale à celles de
ses deux fils. Pour tous A et B nœuds de l'arbre tels que B soit un fils de A, clé(A) ≥ clé(B). Dans ce
cas, le plus grand élément de l'arbre est à la racine.
On parle d'un tas-min (Min-heap) si tout nœud a une valeur plus petite ou égale à celles de ses
deux fils. Pour tous A et B nœuds de l'arbre tels que B soit un fils de A, clé(A) <= clé(B). Dans ce
cas, le plus petit élément de l'arbre est à la racine.
3. L'élément le plus prioritaire se trouve donc toujours à la racine.
Exemple d'un tas-max

31
Chapitre 3 : Les Arbres

Exemple d'un tas-min

Contre-exemples d'un tas

-L'arbre A n'est pas un tas car il n'est pas parfait calé à gauche.
-L'arbre B n'est pas un tas car il viole la propriété de tas , un nœud de valeur 10 ne devrait pas être le fils
d'un nœud de valeur 9.

4.2. Implémentation d'un tas


-Les tas peuvent être implémentés dynamiquement exactement comme les ARB, et sont utilisés par le
même modèle.
-Représentation statique séquentielle :Une représentation statique très efficace utilisant des tableaux
est très utilisée en pratique,elle consiste à ranger les éléments du tas dans un tableau selon un
parcours en largeur : le fils gauche d'un élément d'indice i se trouve toujours s'il existe à la position 2i,
et son fils droit se trouve à la position (2i + 1) et son père se trouve à la position i/2.

32
Chapitre 3 : Les Arbres

4.3. Opérations sur les tas


1- Ajout : Lʼajout d'un élément a un tas ce fait de la manière suivante :
a. Créer un nœud contenant la valeur de cet élément,
b. Attacher ce nœud dans le dernier niveau dans la première place vide le plus à gauche possible. On
obtient toujours un arbre binaire parfait mais pas nécessairement un tas.
c. Comparer la clé du nouveau nœud avec celle de son père et les permuter si nécessaire, puis
recommencer le processus jusqu'il n'y ait plus d'éléments à permuter.
Exemple : soit à ajouter l'élément 15

La complexité de cette opération est de O(Log(n)) ; n est le nombre d'éléments.


2-Retrait : L'élément le plus prioritaire se trouve toujours à la racine, donc le retrait consiste à lire la
racine puis la supprimer. Pour ce faire on doit :
a. Remplacer la valeur de la racine par la valeur de l'élément le plus à droite dans le dernier niveau.
b. Supprimer de l'arbre cet élément (le plus à droite dans le dernier niveau), on obtient un arbre binaire
mais pas nécessairement un tas.
c. On compare la valeur de la racine avec les valeurs de ses deux fils et on la permute avec la plus
grande (ou la plus petite). On recommence le processus jusqu'il n'y ait plus d'éléments à permuter.
Exemple de retrait

33
Chapitre 3 : Les Arbres

La suppression est aussi en O(Log(n)) ; n est le nombre d'éléments.

Remarque

La recherche d'un élément dans un tas n'est pas très efficace. Les tas sont généralement utilisés pour
des opérations d'insertion et dʼextraction. Si la recherche est une opération fréquentes ,d'autres
structures de données comme les ABR sont plus appropriées.

4.4. Tri par tas (Heapsort)


4.4.1 Principe de l'algorithme
Le tri par tas est un algorithme de tri par comparaison, plutôt efficace et qui a une complexité en O(N
log N) .C'est un algorithme de tri non stable mais en place.
L'algorithme du tri par tas repose sur un élément fondamental : le tas (d'où son nom). En effet, ce tri
crée un tas max du tableau donné en entrée, et le parcourt afin de reconstituer les valeurs triées dans
notre tableau, dʼoù le pseudo-code de l'algorithme :
1-Construire le tas max du tableau.
2-Pour chaque élément du tableau
Placer la racine du tas dans le tableau (à la fin pour un tri croissant et au début pour un tri
décroissant).
Entasser (conserver la structure de tas) le dernier élément du tas à la place de la racine.

Tri par tas des éléments : 1, 9, 3, 7, 6, 1, 4. Exemple

On prend la suite de nombres suivante que l'on va trier dans l'ordre croissant avec le tri par tas : 1, 9, 3,
7, 6, 1, 4.
-1ère étape : créer le tas (max dans notre cas)

34
Chapitre 3 : Les Arbres

Dʼoù le tas-max suivant :

-2ème étape : parcourir le tas pour trier les éléments


Pour trier les éléments grâce à notre tas, on retire la racine à chaque tour (l'élément le plus grand de
notre tas, et donc de notre tableau), on le range à sa place définitive, et on entasse le dernier élément
du tas pour combler le trou de la racine mais aussi respecter les règles d'un tas.

Comme la montre la figure en haut :


(1) La racine du tas (en vert) est placée dans le tableau.
(2) Le dernier élément (en bleu) va remplacer la racine.
(3) mais il ne faut pas oublier de l'entasser pour respecter les règles du tas max .

35
Chapitre 3 : Les Arbres

On continue ces opérations tant que le tas contient des éléments :

36

Vous aimerez peut-être aussi