Types Structurés et Algorithmes de Tri
Types Structurés et Algorithmes de Tri
Support de cours
M. DEMBELE
(MASS II / 2005-2006)
PLAN
Chapitre I Les types structurés……...…………………………………………………….2
I-1 Définition………………………………………………………….……………………3
I-2 Les tableaux…………………………………………………………………………….3
I-3 Les ensembles…………………………………………………………………………..4
1
I - LES TYPES STRUCTURES
2
I – 1 Définition
Tout d’abord il faut remarquer que les types de bases que l’on utilisait
jusqu’ici ne nous permettent pas de représenter aisément de nombreuses valeurs
simultanément (les notes d’une classe, les propriètés de plusieurs individus,…). Ceci
a conduit à l’élaboration de types structurés qui peuvent être vus comme des
structures de données complexes composées de types de base. Ils sont donc obtenus
en regroupant des éléments de même type sous un seul nom (tableau, ensembles,…).
Une fois le type structuré crée, on ne peut accéder à ses éléments qu’en
utilisant les opérations de bases qui correspondent à ce type. La représentation de la
structure est alors cachée.
I – 2 Les Tableaux
Les tableaux, considérés comme des types structurés, sont donc composés
d’éléments de même type. On peut avoir un tableau d’entiers, de caractères, de
tableaux, d’enregistrements,… Les éléments d’un tableau sont rangés de façon
contiguë.
I 1 2 3 4 5 6 7 8 9
Tab Tab[1] Tab[2] Tab[3] Tab[4] Tab[5] Tab[6] Tab[7] Tab[8] Tab[9]
Exemple
Pour i ß 1 à 9 faire Tab[i] := i ;
I 1 2 3 4 5 6 7 8 9
Tab 1 2 3 4 5 6 7 8 9
3
• Type de composantes: toutes identiques (le type T). Un tableau ne peut pas
contenir des composantes de type différent.
Puisqu’un tableau peut être composé de tableaux, on peut obtenir des tableaux
multidimensionnels.
• Sélecteur:
var m : Matrices;
m[i][j] ou m[i,j].
Le nombre de dimension d’un tableau n’est, dans la plupart des langages, pas
limité!
I – 3 Les ensembles
Exemples:
var S, Voyelles, Consonnes : set of char;
S := [ ]; Voyelles := [ ‘a’, ‘e’, ‘i’, ‘o’, ‘u’, ‘y’ ]; Consonnes := [ ‘b’..‘d’, ‘f’..‘h’, ‘j’..‘n’,
‘p’..‘t’, ‘v’..‘x’, ‘z’ ];
4
Remarques :
5
II - LES ALGORITHMES DE TRI
6
II – 1 Le problème du tri
Le tri est une opération qui a pour but de classer des objets, des documents,
des articles, …, dans l'ordre croissant ou décroissant suivant une propriété (date de
publication, auteur, taille,…) ou un numéro d'ordre attachés à chacun de ces objets. Il
est nécessaire que cette propriété ou ce numéro appartiennent à un ensemble
ordonné au sens mathématique (par exemple ordre lexicographique ou numérique).
Cet ensemble ordonné est appelé critère de tri. On peut donc se représenter les
éléments à trier comme un ensemble d’enregistrements dont la structure est la
suivante :
Clé ti Informations Di
Avec ( i = 1, ..., n )
Le but d'une opération de tri est de réaliser une permutation des indices pour que les
clés vérifient la relation d’ordre.
Exemple :
55 Aminata Fall
72 Ibrahima Diouf
68 Khady Mdodj
.. …
.. …
Les informations correspondent aux étudiants et le critère de tri est le poids. Le but
du tri est d’effectuer une permutation pour ranger ces éléments suivant le poids.
II – 2 Spécification du tri
II – 3 Méthodes de tri
II – 3 – 1 Tri à bulles
Méthode de tri dans laquelle des paires de valeurs adjacentes dans la liste à
trier sont comparées et échangées si elles ne sont pas dans le bon ordre. Ainsi, lors
des passages, les entrées de la liste (ou du tableau) remontent comme des bulles.
7
Exemple : soit le tableau suivant à trier:
13 4 2 1 9
La première itération qui nous permet de comparer les éléments et de les échanger
repousse le plus grand élément au bout du tableau.
La deuxième laisse le 9 à sa place
13 4 2 1 9
4 13 2 1 9
4 2 13 1 9
4 2 1 13 9
4 2 1 9 13
La 2ème itération
4 2 1 9 13
La 3ème itération
4 2 1 9 13
2 4 1 9 13
2 1 4 9 13
1 2 4 9 13
Algorithme :
tri_bulle(T)
DEBUT
Permutation ß vraie
Tant qu’on effectue des permutations
DEBUT
Permutation ß faux;
Pour i allant de 1 à n-1 faire si T[i+1]<T[i] alors
DEBUT
permuter(T[i+1],T[i]);
permutation = vraie;
FIN
FIN
FIN
8
Exemple :
Le premier parcours du tableau révèle l’élément 1 comme le plus petit, il faut le
permuter avec l’élément 13. La deuxième itération retrouve le second plus petit
élément, c'est-à-dire 2, et le permute avec le deuxième élément du tableau 4.
13 4 2 1 9
1 4 2 13 9
A la 2ème itération
1 4 2 13 9
1 2 4 13 9
Algorithme :
tri_selection(T)
DEBUT
Pour i allant de 1 à n-1 faire
DEBUT
k ß i;
pour j allant de i+1 à n faire si T[j]<T[k] alors k ßj;
permuter (T[i],T[k]) ;
FIN
FIN
On suppose que les i-1 premiers éléments du tableau sont triés dans l’ordre
croissant. Il faut maintenant insérer le ième élément à la bonne place dans la liste déjà
ordonnée.
Exemple :
Au départ on ne considère que le premier élément, soit 13, et on suppose qu’il est trié
puisqu’il est seul. On passe à l’élément 4. Il faut le placer correctement.
13 4 2 1 9
4 13 2 1 9
A la 2ème itération
4 13 2 1 9
2 4 13 1 9
A la 3ème itération
2 4 13 1 9
9
Algorithme :
tri_insertion (T)
DEBUT
Pour i allant de 2 à n
DEBUT
el ß T[i];
jßi-1;
TANT QUE j>0 et el<T[j]
DEBUT
T[j+1]ßT[j];
jßj-1;
FIN
T[j+1]ß el;
FIN
FIN
II – 3 – 4 Récursivité
II – 3 – 4 – 1 Définition
Le premier qu’on a déjà utilisé est le tableau de tableaux. Cela suppose que les
tableaux qui constituent le premier peuvent aussi être constitués de tableaux et ainsi
de suite.
On dira donc, en termes informatiques, qu’un objet est récursif, s'il se contient lui-
même ou s'il est défini à partir de lui-même. L’objet que nous utiliserons ici est la
fonction, puisqu’elle permet d’implémenter une tache, et on ira qu’une fonction
récursive est une fonction qui s’appelle elle-même dans sa définition.
Attention !
10
II – 3 – 4 – 2 Programme itératif et programme récursif
II – 3 – 4 – 3 Exemples
Calcul du factoriel.
factoriel(n)
DEBUT
FIN
Nombre de Fibonacci.
Fibo(0) = Fibo(1) =1
Fibo(n)=Fibo(n-1)+Fibo(n-2);
Fibo(n)
DEBUT
FIN
11
II – 3 – 4 – 4 Le tri rapide
Exemple :
Algorithme :
tri_rapide(T,deb,fin)
DEBUT
si deb<fin alors
DEBUT
k=pivot(T,deb,fin);
tri_rapide(T,deb,k-1);
tri_rapide(T,k+1,fin);
FIN
FIN
On voit bien que l’on sépare le tableau avec la fonction pivot (qui est donnée ci-
dessous) en deux. Ensuite on a qu’à appliquer le même processus aux deux tableaux
obtenus. C’est bien de la récursivité.
12
pivot(T,i,j)
DEBUT
l=i+1;
k=j;
DEBUT
Si (l<k)
DEBUT
permuter(T[l],T[k]);
k=k-1;
l=l+1;
FIN
FIN
permuter(T[i],T[k]);
renvoyer (k);
FIN
Exemple :
13 4 2 1 9
13 4 2 1 9
Il faut maintenant appliquer le même processus aux deux parties puis les fusionner.
On obtient :
13
13 4 2 1 9
Algorithme
tri_fusion (T,deb,fin)
DEBUT
Si deb<fin
DEBUT
k ß (deb+fin)div2
tri_fusion (T,deb,k);
tri_fusion (T,k+1,fin);
fusion(T,deb,k,fin);
FIN
FIN
14
fusion(T,i,k,j)
DEBUT
sßi ; tßk+1 ; rßi ;
Tant que (s<=k) et (t<=j)
DEBUT
| SI (T[s]<T[t])
| DEBUT
| | Tab[r]ßT[s];
| | sßs+1 ;
| | rßr+1 ;
| FIN
| SINON
| DEBUT
| | Tab[r]ßT[t];
| | tßt+1 ;
| | rßr+1 ;
| FIN
FIN
SI (s>k)
POUR u allant de t à j
DEBUT
| Tab[r] ß T[u];
| rßr+1 ;
FIN
SINON
POUR u allant de s à k
DEBUT
| Tab[r] ß T[u];
| rßr+1 ;
FIN
Tß Tab ;
FIN
15
III - LES ENREGISTREMENTS
16
III – 1 Définition
Exemple :
17
III – 3 Accès et écriture
Affectation :
[Link] :=’Diop’ ; [Link] :=’Ibou’ ; [Link] :=Masc ;…
On peut également affecter un enregistrement à un autre : personne2 :=personne1 ;
On obtient alors les mêmes valeurs pour chaque champ.
Attention !!!
Il n'est pas possible de construire une valeur d'une variable de type enregistrement
en utilisant directement son identificateur dans une instruction Read ou Readln. Par
exemple, l'instruction Read(personne1); n'est pas permise. Par contre, il est tout à fait
légal de l'écrire de la manière suivante: Read([Link], [Link]).
Permet l'accès direct aux champs d'un enregistrement. Les identificateurs des
champs serviront dès lors d'identificateurs de variables
Exemple :
VAR P: TPersonne;
la séquence:
[Link] := 'Diop';
[Link] := 'Mamadou';
[Link] := Masc;
[Link] := 2500;
[Link] := 30;
[Link] := Marie;
peut s'écrire:
WITH P DO
BEGIN
Nom: = 'Diop' ;
Prenom := 'Mamadou';
Sexe := Masc;
Mat := 2500;
Age := 30;
Etat := Marie
END;
18
Vu qu’un champ peut aussi se présenter sous forme d’un autre enregistrement,
l’imbrication d’instructions with est possible.
Exemple :
TPersonne = RECORD
Nom, Prenom: String;
Age: TAge;
Sexe: TSexe;
CASE Etat: TEtatCivil OF
Celibataire: ( Seul: Boolean);
Marie: ( DateMariage: TDate; LieuMariage : String ;
Conjoint: RECORD
NomConjoint, PrenomConjoint: String
END;
NombreEnfants: 0..10 );
Divorce: ( DatePremierMariage, DateDivorce: TDate;
Nombre Enfants: 0..10 );
Veuf: ( DateMariage: TDate; NombreEnfants: 0..10 );
Concubin: ( )
END;
19
Pour toute personne, on aura comme partie fixe son nom, son prénom, son âge, son
sexe et son état civil. Pour une personne célibataire, on mentionnera le fait qu'il vive
seul ou non seul. Pour une personne mariée, on aura la date du mariage, le lieu du
mariage, le nom et le prénom du conjoint et le nombre d'enfants. Pour une personne
divorcée, on aura la date du premier mariage, la date du divorce et le nombre
d'enfants. Enfin, pour une personne veuve, on aura sa date de mariage et le nombre
de ses enfants.
Exemple :
VAR P: TPersonne;
[Link] := Celibataire;
20
Attention !!!
La partie fixe doit toujours précéder la partie variable et on ne peut avoir qu’une
seule partie variable.
Si pour un cas donné, la liste des champs éventuels est vide, il faut écrire () . C’est le
cas pour concubin.
Exemple :
21
IV - LES FICHIERS
22
IV – 1 Définition
à la création de fichier
à l’ouverture d'un fichier
à la lecture dans un fichier
à l’écriture dans un fichier
à la fermeture d'un fichier
à La destruction d'un fichier
IV – 2 Accès
En Pascal tous les modes d’accès sont autorisés. On ne parlera donc pas de fichier
séquentiel ou de fichier à accès direct mais on parlera d’accès direct ou séquentiel à
un fichier. Le choix du mode d’accès dépend de plusieurs facteurs :
à le support du fichier : sur disque, tous les accès sont possibles ; sur bande seul
l’accès séquentiel est possible.
23
à le temps de réponse : si le temps de réponse doit être faible, on évitera aussi l’accès
séquentiel.
Tous les types sont autorisés pour les éléments, sauf le type fichier !!!
Exemples :
ADRESSE = record
.....................
end;
REPERTOIRE = file of ADRESSE ;
COORDONNES = record
abscisse, ordonnee : real ;
end ;
TRACE = file of coordonnees ;
Autre possibilité :
24
IV – 3 – 2 Création d’un fichier
Cette instruction permet d'ouvrir un fichier 'en écriture', c'est-à-dire de créer le fichier,
et d'autoriser des opérations d'écriture dans ce dernier.
C'est une méthode, parfois nécessaire, qui varie selon le système informatique. Elle
n'est pas standard et diffère selon les compilateurs Pascal. Bien souvent, il est
nécessaire de différencier le nom interne du fichier, de son nom externe. Le nom
interne (ou nom logique) correspond au nom utilisé dans le programme. C'est donc
l'identificateur déclaré comme variable (ex : Var F : file of ...). Il s'agit donc du nom de
fichier vu par le programmeur et par le programme Pascal. Le nom externe (ou nom
physique) représente quant à lui le nom utilisé sur le disque, visible dans le
répertoire (dossier ou directory). Il s'agit donc du nom de fichier vu par l'utilisateur
et par le système d'exploitation.
Pour associer les deux noms en Turbo Pascal, on utilise la fonction assign :
Assign(ID_FICHIER_INTERNE, ID_FICHIER_EXTERNE);
Exemple :
assign(FICH,'a :[Link]') ;
Attention ! Il ne faut surtout pas oublier de refermer tous les fichiers ouverts grâce à
l'instruction close(fichier).
L'écriture dans un fichier est quasiment analogue à l'affichage d'une donnée à l'écran.
Il suffit simplement d'ajouter le nom logique du ficher.
25
Syntaxe : write (F,x)
Attention ! Le type de x doit être compatible avec le type déclaré par le fichier.
Etat du fichier :
Dans un fichier séquentiel, pour pouvoir lire une donnée, il est impératif que le
fichier ait d'abord été ouvert 'en lecture'. Cela signifie qu'il n'est pas possible de lire
des informations dans un fichier ouvert avec Rewrite (ouverture 'en écriture'). Pour
la lecture, il ne faut donc pas initialiser le fichier avec l'instruction Rewrite, sinon
toutes les anciennes données du fichier seront perdues, le fichier sera écrasé lors de
cette réinitialisation. Il est alors nécessaire d'utiliser une autre instruction permettant
l'ouverture du fichier en mode lecture : l'instruction Reset.
Comme pour l'écriture, la lecture dans un fichier est quasiment analogue à saisie
d'une donnée au clavier. Il suffit là encore d'ajouter le nom du ficher.
26
Syntaxe : read (F,x)
Etat du fichier :
IV – 3 – 7 Fonctions de manipulation
flush(F) : vide le buffer associé au fichier F. Au niveau physique, les transferts se font
à travers une mémoire tampon.
27
filepos(F) : retourne le numéro courant. Chaque enregistrement possède un numéro
d’enregistrement, le premier se voit attribuer le numéro 0. On a donc Rang=Numéro
d’enregistrement + 1.
IV – 3 – 8 Exemples
Création :
...
Assign(fic,'[Link]');
Rewrite(fic);
Readln([Link]);
While [Link] <> 'zzz' Do
Begin
Readln([Link]);
Write(fic, personne);
Readln([Link])
End;
Close(fic) ;
Lecture:
...
Assign(fic,'[Link]);
Reset(fic);
While Not EOF(fic) Do
Begin
Read(fic, personne);
With personne Do Writeln(Nom, ' ', Prenom);
End;
Close(fic)
...
28
Modification :
...
Assign(fic,'[Link]);
Reset(fic);
If FileSize(fic) >= 3 Then
Begin
Seek(fic, 2);
Read(fic, personne);
Write([Link]);
With personne Do
Begin
Readln(Nom);
Readln(Prenom)
End;
Seek(fic, FilePos(fic)-1);
Write(fic, personne)
End;
Close(fic)
...
Lorsqu'un fichier est défini sous forme text, on dit qu'il s'agit d'un fichier de texte.
Les formes d'écriture d'un fichier de texte ne diffèrent pas de celles des autres fichiers.
Le problème se pose, dans ce cas, de séparer le fichier en lignes. Il est donc nécessaire
de diposer d'un mécanisme pour indiquer le passage à la ligne. Pour cela, utiliser les
procédures Readln et Writeln.
La fonction booléenne Eoln (End of line) : Cette fonction est utilisable pour le
traitement des fichiers de texte. Elle retourne la valeur True, lorsqu'une fin de ligne
est atteinte, sinon False.
Var
F : Text;
rep : char;
Procedure ECRIT;
Var
c : char;
Begin
Rewrite(F, 'fichier textuel' );
Writeln( ' Tapez un texte et terminez par $' );
Repeat
read(c);
if c <> '$'
then
29
if EOLN(F)
then
writeln(F,c)
else
write(F,c);
Until c='$';
Close(F);
End;
Procedure LIT;
Var
s : string;
Begin
Reset(F, 'fichier textuel' );
Writeln;
Repeat
readln(F,s);
writeln(s);
Until EOF(F);
Close(F);
End;
30