Algirithme Coregie
Algirithme Coregie
Chapitre 6 : La Récursivité 30
Références bibliographiques 54
Chapitre 1:
Généralités et Notions de Base
1. Introduction
L'algorithmique est l'étude des algorithmes. Un algorithme est une méthode permettant de
résoudre un problème donne en un temps fini ;
La réalisation d'un programme passe par l'analyse descendante du problème : il faut réussir
à trouver les actions élémentaires qui, en partant d'un environnement initial, nous conduisent à
l'état final. Une fois ces actions déterminées, il suffit de les traduire dans le langage de
programmation choisi.
Page 4
Chapitre 1:
2. Base d’un langage algorithmique
Le langage algorithmique est un langage générique permettant de traiter tous type de
problème par la concaténation des instructions.
Algorithme Nom-d’Algorithme ;
Début
. …..
. ………..
Fin.
La partie déclaration permet de spécifier quelles seront les variables utilisées au cours de
l’algorithme ainsi que le type de valeur quelles doivent respectivement prendre.
Page 5
Chapitre 1:
2.2.1. Entier : (1,2, 3,….)
Le type entier caractérise l’ensemble des nombres entiers. Les opérations arithmétiques
possibles sur ce type sont : L’addition ‘+’, ‘-‘, ‘*’, ‘/’. Appliquées sur des opérandes de type
entier, elles fournissent un résultat entier sauf l’opération ‘/’ qui fournit un résultat réel.
Tandis que les opérations de relation notées par ‘<’, ‘>’, ‘>=’, ‘<=’, ‘<>’ fournissent un
résultat logique.
Exemples :
Const x = 1 ;
Var A : entier ;
Var A, b : entier ;
Exemples
Var A : réel ;
Var A, b : réel ;
Exemples :
Const x = 1.1 ;
Var A : Caractère ;
Page 6
Chapitre 1:
Var A, b : Caractère ;
OU, NON, appliqués à des opérandes de type booléen fournissent un résultat booléen.
Exemples :
Const x = ‘a’ ;
Var A : Booléen ;
Var A, b : Booléen;
Exemple
Quels sont les identificateurs valides et ceux qui ne sont pas valides ?
Page 7
Chapitre 1:
M, ax, 8b, s_m, farid, exo1, exo ?, 34, then, nom programme, ….
2.4. Instructions
Une instruction est une action élémentaire commandant à l’ordinateur un calcul, une
instruction de base peut être :
L’affectation est l’action élémentaire principale puisque c’est par son intermédiaire
que l’on peut modifier la valeur d’une variable, elle a pour syntaxe : Variable← valeur ou
variable ←expression ;
Exemple
Algorithme exemple-Affectation ;
Var A, B : Entier ;
Debut
………………..
A←10 ;
B← A+15 ;
Fin.
A_10 ;
B_5 ;
A_A+B ;
Page 8
Chapitre 1:
Pour affichage sur écran
L’affichage est l’action élémentaire permettant à un algorithme de fournir des résultats à
l’utilisateur, il se fait par l’intermédiaire de la commande (Fonction) Ecrire.
A_10 ;
B _5 ;
C_A+B ;
(Fonction) Lire.
A_10 ;
Lire (B) ;
C_A+B ;
A_1 ;
B_10 ;
Page 9
Chapitre 1:
C_A*2+B-3 ;
Ecrire (C) ;
….
2.5. Commentaires
Un commentaire est un texte facultatif (des phrases) situé entre les symboles et { et } qui n’a
aucun effet sur le fonctionnement du l’algorithme. Elle sert à expliquer le pourquoi de
certaines instructions utilisés dans un programme.
Exemple
Algorithme exo ;
Var A : entier ;
Debut
Lire (A) ;
Lire (B) ;
C :=A+B ;
Ecrire (C) ;
Fin.
2.6. Expressions
Une expression est une combinaison de plusieurs opérandes (éventuellement des fonctions) et
opérandes. Ils existent plusieurs types d’expressions :
Page
10
Chapitre 1:
Exemple : a + b – c/d est une expression arithmétique
Une expression est évaluée suivant la priorité des operateurs, on commençant par le plus
prioritaire. Dans le cas ou deux operateurs ont la même priorité, on commence par la plus à
gauche.
Non (not)
/ div
Priorité et (and)
+ - mod
Ou (or)
Les parenthèses ouvrantes et fermantes sont considérées des opérateurs les plus prioritaires.
Exemple : a ← b div 5 ;
Exemple : a ← b mod 5 ;
3. Conclusion
Ce chapitre permet de se familiariser avec le langage algorithmique afin d’écrire des petits
algorithmes pour résoudre des petits problèmes. Cependant, les instructions vues dans ce
chapitre sont omniprésents dans tous les futurs algorithmes.
Page
11
Chapitre 2:
Les Structures de Contrôle
1. Introduction
On appel structure de contrôle toute action qui permet d’effectuer un groupe d’actions sous
condition(s), et permet donc d’orienter le déroulement d’un programme suivant la réalisation
de ces conditions. Il existe plusieurs formes de structure de contrôle :
Fin_si
Si la condition définie dans <Condition> est vérifiée il faut exécuter l’action (ou le
groupe d’action) définie dans <Action 1>, puis les actions qui suivent le fsi
Si cette condition n’est pas vérifiée il faut exécuter l’action (ou le groupe d’actions)
définie dans <Action 2>, puis les actions qui suivent le fsi.
L’organigramme associé est :
Et dans ce cas :
Page
12
Chapitre 2:
Si la condition <Condition> est vérifiée, l’action (ou le groupe d’actions) <Action 1> est
exécutée puis les actions qui suivent le fsi.
Par contre si la condition n’est pas vérifiée, seules les actions qui suivent le fsi seront
exécutées.
Sa forme est :
<Action>
Fin_tq ;
Cette action spécifie qu’une action (ou groupe d’actions) doit être répétée tant que la
condition reste vérifiée.
Page
13
Chapitre 2:
Sa forme est :
<Action>
Fin_Pour ;
Cette action permet de répéter une action (ou groupe d’actions) un nombre de fois déterminé
par les valeurs initiale et finale de paramètre <nom_var>. La partie action est exécutée la
première fois en affectant au paramètre <nom_var> que l’on appelle aussi compteur, la valeur
Page
14
Chapitre 2:
5. L’action répétitive ‘répéter--------jusqu'à’
Cette action permet de répéter une action (groupe d’actions) jusqu'à ce que la condition soit
vérifiée. Sa forme est la suivante :
Repeter
<Actions>
Jusqu'à (condition)
Remarque : L’action est exécutée au moins une fois à l’inverse de l’action répétitive
«tantque » ou l’action ne peut être exécutée
Case variable of
1 : Action 1 ;
2 : Action 2 ;
Default: Action n;
Fin;
: peut être une constante ou plusieurs constantes séparées par des virgules ou bien un
intervalle
Page
15
Chapitre 2:
Cas ch of
sinon
fin,
7. Conclusion
Les structures de contrôles sont très importantes pour contrôler le déroulement des
algorithmes, chacune est adéquate pour une situation donnée afin d’optimiser l’exécution des
algorithmes.
Page
16
Chapitre 3:
Les Tableaux
1. Introduction
Imaginons que dans un programme, nous avons besoin simultanément de 12 valeurs (par
exemple, des notes pour calculer une moyenne). Evidemment, la seule solution dont nous
disposons à l’heure actuelle consiste à déclarer douze variables, appelées par exemple : Notea,
Noteb, Notec, etc. Bien sûr, on peut opter pour une notation un peu simplifiée, par exemple
N1, N2, N3, etc. Mais cela ne change pas fondamentalement notre problème, car arrivé au
calcul, et après une succession de douze instructions « Lire » distinctes, donnera
obligatoirement une atrocité du genre :
Moy ← (N1+N2+N3+N4+N5+N6+N7+N8+N9+N10+N11+N12)/12 ;
C’est pourquoi la programmation nous permet de rassembler toutes ces variables en une seule,
au sein de laquelle chaque valeur sera désignée par un numéro. Autrement dit, cela donnerait
donc quelque chose du genre « la note numéro 1 », « la note numéro 2 », « la note numéro 8
». C’est largement plus pratique.
Page
17
Chapitre 3:
2.1. Déclaration des tableaux à une dimension
Un tableau à une dimension est déclaré de la manière citée ci-dessous, en précisant le nombre
et le type de valeurs qu’il contiendra.
Exemples
Tab : tableau [1..100] d’entiers ;
Note : tableau [1..10] de réels ;
2.2. Remarques
Les cases du tableau (éléments) sont numérotées à partir de 1,
Lors de déclaration du tableau, on précise la plus grande valeur de l’indice, qui est le
nombre d’éléments du tableau
Page
18
Chapitre 3:
4. Tableaux à N dimensions
Un tableau à N dimensions est déclaré de la manière citée ci-dessous, en précisant le nombre
et le type de valeurs qu’il contiendra.
Exemples
Achat : tableau [1..100, 1..100, 1…300] d’entiers ;
Vente : tableau [1..10, 1..47, 1..12, 1..7] de réels ;
Le premier est un tableau à trois dimensions et le deuxième est un tableau à quatre
dimensions.
La référence d’un élément dans un tableau à N dimensions, se fait de la même manière que
celle pour un tableau à une ou à deux dimensions, en précisant l’indice de chaque dimension.
5. Conclusion
Les tableaux sont des structures de programmation statiques, la taille de tableau doit être
précisée à l’avance. Un espace mémoire peut être réservé sans être utilisé si un tableau n’est
pas exploité complètement. Un tableau, une fois déclaré, sa taille ne peut pas être modifiée.
Page
19
Chapitre 4:
Les Fonctions et les Procédures
1. Introduction
Les fonctions et les procédures sont appelés aussi les sous-programmes, elles fournissent aux
programmeurs un moyen simple d’abstraction en lui permettant de nommer une séquence
d’instructions et de l’appeler autant de fois qu’il sera nécessaire au cours d’un même
programme. En outre, les langages de programmation tels que Pascal, permettent de passer
des données à la procédure ou la fonction. Les valeurs de ces données pouvant variés d’un
appel à l’autre, ce mécanisme est appelé passage de paramètres. Un sous-programme
(fonction ou procédure) à la même structure qu’un programme, les seules différences
importantes sont les notions de paramètres et de variables locales.
2. Fonctions
Une fonction est un ensemble d’instructions qui forment un sous-programme, les fonctions en
algorithmique (programmation) ressemblent à celles de mathématique, Chaque fois que l’on
appelle elle renvoie au programme appelant une valeur qui est le résultat du traitement
effectués par des instructions de la fonction. Une fonction peut renvoyer n’importe quel type
de base.
Fonction NomFonction (Var1 : type1, Var2 : type2, …VarN : typeN) : Type ; {l’entete
de la fonction}
Begin
End ;
Page
20
Chapitre 4:
Type est le type de résultat retourné.
Instructions est le calcul effectué par la fonction.
Exemple : Calcul de
Algorithme CalculCNP ;
Var t, i : entiers ;
Debut
T ←1 ;
Debut
T ← t*i ;
Fin ;
Fin ;
Debut
Lire (n,p) ;
Cnp ←fact(n)/(fact(n-p)*fact(p)) ;
Page
21
Chapitre 4:
Ecrire (‘cnp=’,cnp);
Fin.
Par contre ceux qui les remplacent dans les appels des fonctions sont appelées paramètres
effectifs ou réels.
3. Procédures
Le deuxième type de sous-programme est appelé procédure. La procédure ressemble
parfaitement à la fonction sauf que cette dernière peut renvoyer zéro ou plusieurs résultats.
Begin
End;
Page
22
Chapitre 4:
Où : Nom_procedure est le nom de la procédure (Identificateur)
les dernières instructions dans une procédure sont généralement réservées pour
affecter les résultats de traitement effectué par la procédure aux paramètres de sortie
de cette dernière.
Les notions de variables globales, locales, les paramètres formels et effectifs pour les
procédures ont les mêmes significations que pour les fonctions.
L’appel d’une procédure se fait en écrivons son nom et en remplaçons les paramètres
formels par les paramètres effectifs.
4. Fonctions prédéfinies
Ils existent certaines fonctions et procédures prédéfinies, et intégrées avec les langages de
programmation (Pascal). Citons à titre d’exemple : Read (pour la lecture des donnés), write
(pour l’affichage des résultas), Textcolor (numéro) (pour modifier la couleur de texte),
gotoxy (x,y) (pour positionner le curseur au point de coordonnées x, y au moment de
l’exécution), clrscrn (pour effacer l’écran), sound (numéro) (pour déclencher un bip sonore),
…
5. Conclusion
Les sous programmes (fonctions et procédures) sont des portions des programmes qui se
répètent souvent soit dans un même programme, soit dans plusieurs programmes, il est donc
préférable de les écrire une fois pour toute, et de les utiliser au besoin. Ils aussi à simplifier le
développement des programmes volumineux.
Page
23
Chapitre 5:
Les Enregistrements et les Fichiers
1. Introduction
Jusqu’à présent, les informations utilisées dans nos programmes ne pouvaient provenir que de
deux sources : soit elles étaient inclues dans l’algorithme lui-même, par le programmeur, soit
elles étaient entrées en cours de route par l’utilisateur. Mais évidemment, cela ne suffit pas à
combler les besoins réels des informaticiens. Les fichiers servent à stocker des informations
de manière permanente, entre deux exécutions d’un programme. Car si les variables
classiques, qui sont des adresses de mémoire vive, disparaissent à chaque fin d’exécution, les
fichiers, eux sont stockés sur des périphériques à mémoire de masse (disquette, disque dur,
CD Rom…).
Remarques :
'x' chaine de taille et de longueur courante égale à 1. C'est aussi un constant caractère
Page
24
Chapitre 5:
3. Enregistrement
On peut regrouper au sein d’une même structure des informations n’ayant pas nécessairement
toutes le même type dans une structure appelée enregistrement (Record), par exemple, les
différentes informations (nom, prénom, sexe, nombre d’enfant, …) relatives à un employé
d’une entreprise. C’est un type de données défini par l’utilisateur.
Exemple :
Nom : string[30] ;
Prenom : string[30] ;
Sex : char ;
Nb_enfant : integer ;
End ;
Ces variables (enregistrement ou record) pouvant être manipulé champ par champ de la
même façon que les variables de type simple (entier, caractère, …). Pour ce faire, un champ
d’une variable de type enregistrement est désigné par le nom de la variable, suivi d’un point et
du nom du champ concerné.
Exemple
4. Fichier
4.1. Définition
Des fois, il est nécessaire de conserver certaines données après la fin du programme les ayant
créées, ceci pour une utilisation future, les fichiers ont été conçus pour ces fins.
Un fichier est une structure de données toutes de même type mais dont le nombre n'est pas
connu à priori. L'accès à un élément (à une donnée) du fichier se fait :
Page
25
Chapitre 5:
Séquentiellement c'est-à-dire en parcourant le fichier élément par élément depuis le
début jusqu'à l'élément choisi
Directement en donnant la position de l'élément cherché
Selon une clé chaque valeur de la clé désignant un élément on obtient ainsi l'élément
désiré
Les fichiers sont conservés en mémoire secondaire (disques et bandes magnétiques,
disquettes, flash disk...), les données qui les constituent reste toujours tant que cette mémoire
secondaire n'est pas effacée ou endommagée. Chaque fichier est désigné par un nom et
possède des attributs tels que date de création, taille, icône...
- Les fichiers binaires : Contenant du code binaire représentant chaque élément. Ces
fichiers ne doivent être manipulés que par des programmes!
- Les fichiers texte : appelés aussi imprimables, contenant des caractères et
susceptibles d'être lus, éditées, imprimés....
4.2. Operations sur les fichiers
4.2.1. Création
Pour créer un fichier il faut d’abord définit sa structure : son nom logique et physique, …
Exemple
Mat : string[10] ;
Prenom : string[15] ;
Note: reel;
Fin;
Le fichier sera reconnu par l’algorithme (programme) par un nom dit logique. Le nom logique
est attribué au fichier dans la partie déclaration au moyen d’une variable de type fichier.
Page
26
Chapitre 5:
Exemples
Un fichier n’est reconnu par le SGF (système de gestion des fichiers) que par un nom
physique, et par conséquent, un nom physique est associé au nom logique du fichier.
L’affectation (ou l’association) du nom logique au nom physique est réalisée par la procédure
prédéfinie ASSIGN dont la syntaxe est :
Exemple :
Cela veut dire que fichier1 est le fichier [Link] qui est stocké dans la racine de la partition
«C:»
Remarque : si cette procédure est appliquée sur un fichier déjà existant, son contenu sera
perdu.
Ouverture en mode lecture : c’est une opération qui permet d’ouvrir un fichier
stocké sur disque pour la lecture et la modification grâce à la procédure RESET.
Exemple : Reset (fichier1) ;
Page
27
Chapitre 5:
4.2.3. Fermeture d’un fichier
Une fois l’utilisation d’un fichier est terminée, il faut le fermer par la procédure « CLOSE ».
Changement du nom physique : pour changer le nom physique d’un fichier c’est la
procédure « RENAME ».
Exemple : Rename (fichier1, nom physique2) ;
Page
28
Chapitre 5:
Suppression des enregistrements : Il existe deux techniques pour la suppression des
enregistrements à partir d’un fichier : suppression logique et suppression physique.
1er. Suppression logique : dans la définition de la structure des enregistrements du
fichier, on réserve un champ qui indique l’état de l’enregistrement (supprimé ou non),
ainsi la suppression logique consiste à mettre ce champ à la valeur appropriée.
2e. Suppression physique : elle consiste à recopier le fichier dans un autre fichier
en ne prenons que les enregistrements qui ne sont pas logiquement supprimés. A la fin,
on supprime l’ancien fichier tout entier.
Remarque :Apres une série de suppressions logiques. La suppression physique est
recommandée.
6. Conclusion
Les fichiers sont les seules structures de données qui permettent la sauvegarde permanant des
données, ils sont la structure de base pour les bases de données.
Page
29
Chapitre 6:
La Récursivité
1. Introduction
La récursivité est un concept général qui peut être illustré dans (quasiment) tous les langages
de programmation, et qui peut être utile dans de nombreuses situations.
Exemple :
n!= n (n-1) ! et comme il faut s’arrêter, il faut définir une condition d’arrêt, on pose donc
0 !=1.
Le principe de l’exécution est simple : l’algorithme met de côté (en fait dans une PILE) ce
qu’il ne sait pas faire quitte à les reprendre après. Par conséquent, on doit dire à l’algorithme
comment faire dans les cas les plus simples.
Les conditions d’arrêt : ces cas non récursifs sont appelés cas de base et les conditions que
doivent satisfaire les données dans ces cas de base sont appelées conditions d’arrêt ou de
terminaison. Dans les cas complexes, l’algorithme va faire appel à lui-même en simplifiant
ces cas jusqu’à tomber sur l’une des conditions d’arrêt.
Tout algorithme récursif doit distinguer plusieurs cas, dont l’un au moins ne doit pas
comporter d’appel récursif. Souvent ce sont les cas les plus simples. Sans cela, on risque de
tourner en rond et de faire des exécutions qui ne se finissent pas.
Si ces principes ne sont pas appliqués, l’algorithme risque soit de ne pas produire de résultat,
soit de tourner à l’infini
On doit conduire le programme vers les cas de base : tout appel récursif doit se faire avec des
données plus proches des conditions de terminaison.
Page
30
Chapitre 6:
Théoriquement, on peut toujours dé-récursiver un algorithme récursif, c’est-à-dire le
transformer en algorithme itératif. En pratique, ce n’est pas toujours facile!
On peut seulement déplacer un disque qui se trouve au sommet d’une pile (non
couvert par un autre disque) ;
Un disque ne doit jamais être placé sur un autre plus petit.
Le jeu est illustré dans la figure ci-dessous
La solution s’exprime très facilement par récursivité. On veut déplacer une tour de disques du
pilier de gauche vers le pilier de droite, en utilisant le pilier du milieu comme position
intermédiaire.
Il faut d’abord déplacer vers le pilier du milieu la tour de n-1 disques du dessus du
pilier de gauche (en utilisant le pilier de droite comme intermédiaire).
Il reste sur le pilier de gauche seul le grand disque à la base. On déplace ce disque sur
le pilier de droite.
Enfin, on déplace la tour de n -1 disques du pilier du milieu vers le pilier de droite, au-
dessus du grand disque déjà placé (en utilisant le pilier de gauche comme
intermédiaire).
Page
31
Chapitre 6:
La fonction récursive est donnée comme suit :
Début
si (nb_disques = 1) alors
sinon
fsi
Fin.
L’exécution d’un programme qui utilise la fonction Hanoi avec nombre de disque = 3 produit
le résultat suivant :
Combien de disques ? 3
Page
32
Chapitre 6:
Les nombres de la suite de Fibonacci sont égaux à la somme des deux termes précédents, ils
suivent donc la formule de récurrence :
F(n+2)=F(n)+F(n+1)
-> (2 + 1) + fib(2)
-> 3 + fib(2)
-> 3 + (1 + fib(1))
-> 3 + (1 + 1)
-> 3 + 2
-> 5
5. Conclusion
Certains problèmes peuvent être résolus plus logiquement en utilisant la récursivité.
Les programmes sont plus compacts, plus faciles à écrire et à comprendre. Son usage est
naturel quand le problème à traiter peut se décomposer en deux ou plusieurs sous-problèmes
Page
33
Chapitre 6:
identiques au problème initial mais avec des valeurs de paramètres différentes. Refuser la
récursivité dans ce dernier cas oblige l'utilisateur à gérer lui-même une pile des différentes
valeurs des variables, ce que le système fait automatiquement lors de l'utilisation de la
récursivité.
Page
34
Chapitre 7:
La Complexité Algorithmique
Introduction
On n'exige pas seulement d'un algorithme qu'il résolve un problème, on veut également qu'il
soit efficace, c'est-à-dire rapide (en termes de temps d'exécution) ; peu gourmand en
ressources (espace de stockage, mémoire utilisée). On a donc besoin d'outils qui nous
permettre d'évaluer la qualité théorique des algorithmes proposés. Pour toutes ces raisons,
l’étude de la complexité algorithmique est primordiale.
La notation la plus utilisée pour exprimer la complexité d'un algorithme est la notation O
(pour ordre de...), qui dénote un ordre de grandeur. Par exemple, on dira d'un algorithme qu'il
est O(15) s'il nécessite au plus 15 opérations (dans le pire cas) pour se compléter. En langage
naturel, on dira qu'il est O de 15 ou encore de l'ordre de 15.
1. Chaque instruction basique consomme une unité de temps ; (affectation d'une variable,
comparaison, +, -, *, =, ...). Les instructions de base prennent un temps constant, notée
O(1).
2. Chaque itération d'une boucle rajoute le nombre d'unités de temps consommées dans
le corps de cette boucle ;
3. Chaque appel de fonction rajoute le nombre d'unités de temps consommées dans cette
fonction ;
4. On additionne les complexités d'opérations en séquence :
O(f1(n)) + O(f2(n)) =O(f1(n) + f2(n)).
Page
35
Chapitre 7:
C’est la même chose pour les branchements conditionnels :
5. Pour avoir le nombre d'opérations effectuées par l'algorithme, on additionne le tout
La complexité d'un algorithme est une mesure de sa performance asymptotique (des données
très grandes) dans le pire cas ;
Dans les boucles, on multiplie la complexité du corps de la boucle par le nombre d'itérations.
Page
36
Chapitre 7:
La notation O, dite notation de Landau, vérifie les propriétés suivantes :
On dit que deux fonctions f(n) et g (n) sont équivalentes si f(n)= O (g (n)) et g(n) = o
(f (n))
D'un point de vue algorithmique, trouver un nouvel algorithme de même complexité pour un
problème donné ne présente donc pas beaucoup d'intérêt ;
Lorsque, pour une valeur donnée du paramètre de complexité, le temps d'exécution varie
selon les données d'entrée, on peut distinguer :
Page
37
Chapitre 7:
Conclusion
Page
38
Chapitre 8:
Les Pointeurs
1. Introduction
Un pointeur est une variable dont la valeur est une adresse mémoire. Un pointeur, noté
P, pointe sur une variable dynamique notée P^.
Le type de base est le type de la variable pointée. Le type du pointeur est l'ensemble des
adresses des variables pointées du type de base. Il est représenté par le symbole ^ suivi de
l'identificateur du type de base.
La variable pointeur P pointe sur l'espace mémoire P^ d'adresse 3. Cette cellule mémoire
contient la valeur "Essai" dans le champ Info et la valeur spéciale Nil dans le champ
Suivant. Ce champ servira à indiquer quel est l’élément suivant lorsque la cellule fera partie
d’une liste. La valeur Nil indique qu’il n’y a pas d'élément suivant. P^ est l'objet dont
l'adresse est rangée dans P.
Avec les pointeurs, plusieurs structures de données peuvent être définies : les listes linéaires
chainées, les files d’attente, les piles, les arbres.
Page
39
Chapitre 8:
Un élément ou maillon d’une LLC est toujours une structure (Objet composé) avec deux
champs : un champ Valeur contenant l’information et un champ Adresse donnant l’adresse du
prochain élément. A chaque maillon est associée une adresse. On utilise ainsi une nouvelle
classe d’objet : le type Pointeur qui est une variable contenant l’adresse d’un emplacement
mémoire.
Info : Chaîne
Suivant : Liste
fin Structure
Il faut commencer par définir un type de variable pour chaque élément de la chaîne. En
langage algorithmique ceci se fait comme suit :
Page
40
Chapitre 8:
Info : variant
Suivant : Liste
Fin structure
Le type de Info dépend des valeurs contenues dans la liste : entier, chaîne de caractères,
variant pour un type quelconque…
Une liste linéaire chainée est caractérisée par l’adresse de son premier élément souvent appelé
Tête. Nil constitue l’adresse qui ne pointe aucun maillon, utilisé pour indiquer la fin e la liste
dans le dernier maillon
Page
41
Chapitre 8:
Afin de développer des algorithmes sur les listes linéaires chainées, on construit une machine
abstraite avec les opérations suivantes : Allouer, Libérer, Aff_Adr, Aff_Val, Suivant et Valeur
définies comme suit :
Les principaux traitements qui peuvent être effectué sur des listes sont les suivants :
Page
42
Chapitre 8:
1. Liste chaînée simple constituée d'éléments reliés entre eux par des pointeurs.
2. Liste chaînée ordonnée où l'élément suivant est plus grand que le précédent. L'insertion
et la suppression d'élément se font de façon à ce que la liste reste triée.
3. Liste circulaire où le dernier élément pointe sur le premier élément de la liste. S'il s'agit
d'une liste doublement chaînée alors de premier élément pointe également sur le dernier.
Page
43
Chapitre 8:
4. Listes linéaires chaînées bidirectionnelles : c’est une LLC où chaque maillon contient à
la fois l’adresse de l’élément précédent et l’adresse de l’élément suivant ce qui permet de
parcourir la liste dans les deux sens.
Un modèle sur les listes linéaires chaînées bidirectionnelles est donné comme suit :
3. File
Une file est une structure de données dynamique dans laquelle on insère des nouveaux
éléments à la fin (queue) et où on enlève des éléments au début (tête de file). L’application la
plus classique est la file d’attente, et elle sert beaucoup en simulation. Elle est aussi très
Page
44
Chapitre 8:
utilisée aussi bien dans la vie courante que dans les systèmes informatiques. Par exemple, elle
modélise la file d’attente des clients devant un guichet, les travaux en attente d’exécution dans
un système de traitement par lots, ou encore les messages en attente dans un commutateur de
réseau téléphonique. On retrouve également les files d’attente dans les programmes de
traitement de transactions telle que les réservations de sièges d’avion.
On note bien que dans une file, le premier élément inséré est aussi le premier retiré. On parle
de mode d’accès FIFO (First In Fist Out).
Pour ajouter un nouvel élément, on doit se déplacer en queue de la file en parcourant la file de
début jusqu’à la fin. Lorsque le dernier nœud est atteint, lui accrocher le nouvel élément qui
devient de ce fait le dernier.
Quatre opérations de base sont principalement utilisées dans une file d’attente:
4. Pile
Les piles sont des structures linéaires pour lesquelles à chaque nœud on s’intéresse en
premier lieu non seulement à la valeur stockée mais aussi au moment où celle-ci est arrivée.
Page
45
Chapitre 8:
Une pile est un type de liste particulier dans lesquels toute insertion ou suppression d’élément
se fait à une extrémité appelée sommet de la pile. Pour bien comprendre les mécanismes de
base, il suffit de penser à une pile d’assiettes.
Une pile est une liste sur laquelle on autorise seulement 4 opérations:
Toutes les opérations sont effectuées sur la même extrémité; on parle de structure en FIFO.
5. Arbre
L'arbre est une structure de données qui généralise la liste, alors qu'une cellule de la liste a un
seul successeur (leur suivant), dans un arbre il peut y en avoir plusieurs. On parle alors de
nœud (au lieu de cellule). Un nœud père peut avoir plusieurs nœuds fils. Un fils n'a qu'un seul
père, et tous les nœuds ont un ancêtre commun appelé la racine de l'arbre (le seul nœud qui n'a
pas de père).
Comme les listes, la structure d’arbre est fortement utilisée en informatique, particulièrement
en base de données, pour représenter des algorithmes de recherche opérationnelle, en
traitement d’images, dans les programmes de calcul formel,
Page
46
Chapitre 8:
La racine est l’élément unique de l’arbre à partir duquel on a accès à ses éléments. Tous les
algorithmes de traitement d’arbres partiront de la racine. Pour s’orienter dans un arbre, on
utilise la terminologie classique des arbres généalogiques : père, fils, frères, ascendant,
descendant,… tel que :
Le degré d’un nœud dans un arbre est égale au nombre de fils de ce nœud. Un nœud feuille
est un nœud de degré 0.
Page
47
Chapitre 8:
cette fois sur le sous-arbre gauche puis sur le sous arbre droit. En d’autres mots : le nœud
racine est traité au premier passage avant le parcours des sous-arbres.
ParcoursRGD (ARBIN A)
Début
Si (A est vide) Alors
terminaison (A)
Sinon
traitement (A)
Parcours (ABG de A)
Parcours (ABD de A)
Fsi
Fin
2. Parcours symétrique ou infixe (Gauche Racine Droit): cette fois-ci, le traitement se fait
entre les deux parcours, du sous arbre droit et du sous arbre gauche. En d’autres mots : le
nœud racine est traité au second passage après le parcours du sous-arbre gauche et avant le
parcours du sous-arbre droit.
ParcoursGRD (ARBIN A)
Début
Si (A est vide) alors
Terminaison (A)
Sinon
Parcours (ABG de A)
Traitement (A)
Parcours (ABD de A)
Fsi
Fin
Page
48
Chapitre 8:
ParcoursGDR (ARBIN A)
Début
Si (A est vide) Alors
terminaison (A)
Sinon
Parcours (ABG de A)
Parcours (ABD de A)
Traitement (A)
Fsi
Fin
- en largeur.
- en profondeur
On parcourt par distance croissante à la racine. La figure suivante illustre son principe.
Page
49
Chapitre 8:
Fsi
Si (ABD de A non vide) Alors
Enfiler ABD de A dans F
Fsi
Ftq
Fsi
détruire F
Fin
Page
50
Chapitre 8:
Page
51
Chapitre 8:
static void Affiche(Arbre a) {
i f (a==null) return;
Affiche([Link]);
Affiche([Link]);
[Link]([Link]+" ");
}
Ecriture infixée
Ecriture postfixée
4 12 + 5 * 4 17 + 6 * + 7 8 4 * + /
Ecriture préfixée
/ + * + 3 12 5 * + 4 17 6 + 7 * 8 4
6. Conclusion
Si l'on ne fait pas attention et que l'on accède à une zone mémoire qui ne nous est pas
allouée, le processeur via le système d'exploitation génèrera une erreur de segmentation qui
Page
52
Chapitre 8:
provoquera une exception voire fera planter l'application. De plus, comme les allocations
mémoire sont réalisées en partie par le développeur, il doit également se charger de la
libération de la mémoire lorsqu'il n'en a plus besoin, au risque de voir une fuite mémoire
apparaître.
Page
53
Références Bibliographiques
[3] : Michel Divay, Algorithmes et structures de données génériques - 2ème édition, Edition
Dunod
C, édition CHIHAB,
[6] : Claude Pair, Marie-Claude Gaudel, Les Structures de données et leur représentation en
mémoire, édition Iria, 1979
Page
54