Vous êtes sur la page 1sur 132

Les bases de linformatique - programmation - ( rv. 04.01.

2005 ) page
223
Chapitre 3 : Dvelopper du logiciel
avec mthode
3.1 Dveloppement mthodique du logiciel
- la production du logiciel
- conception structure descendante et machines abstraites
- notion d'algorithme
- un langage de description d'algorithmes le LDFA
- le dossier de programmation
- trace formelle d'un algorithme
- traducteur LDFA - Pascal
- facteurs de qualit du logiciel
Machines abstraites : exemple de traitement sur les chanes
- cas o la version du pascal contient un type chane
- cas o la version du pascal ne contient pas de type chane
- programme pascal obtenu
- autres versions d'implantation en pascal
3.2.Modularit
- dfinition : B.Meyer
- la modularit en pascal avec les Unit
3.3. Complexit, tri, recherche
- Notions de complexit temporelle et spatiale
- Mesure de la complexit temporelle d'un algorithme
- Notation de Landau O(n)
-
Trier des tableaux en mmoire centrale
- Le Tri bulles
- Le Tri par slection
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
224
- Le ri par insertion
- Le Tri rapide QuickSort
- Le Tri par tas HeapSort
Rechercher dans un tableau
- Dans un tableau non tri
- Dans un tableau tri
Exercices: algorithmes et leur traduction
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
225
3.1 : dveloppement mthodique
du Logiciel
Plan du chapitre:
1.Historique des langages
Introduction
1. Production du logiciel
1.1 Gnie logiciel
1.2 Cycle de vie du logiciel
1.3 Maintenance dun logiciel
1.4 Production industrielle du logiciel
2. Conception structure descendante
2.1 Critre simple dautomatisation
2.2 Analyse mthodique descendante
2.3 Analyse ascendante
2.4 Programmation descendante avec retour sur un niveau
2.5 Machines abstraites et niveaux logiques
3. Notion dALGORITHME
3.1 Langage algorithmique
3.2 Objets de base d'un langage algorithmique
3.3 Oprations sur les objets de base d'un langage algorithmique
4. Un langage de description dalgorithme : LDFA
4.1 Atomes du LDFA
4.2 Information en LDFA
4.3 Vocabulaire terminal du LDFA
4.4 Instructions simples du LDFA
5. Le Dossier de dveloppement
5.1 Enonc et spcification
5.2 Mthodologie
5.3 Environnement
5.4 Algorithme en LDFA
5.5 Programme en langage Pascal
6. Trace formelle dun algorithme
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
226
6.1 Espace dexcution dune instruction compose
6.2 Exemple avec trace formelle
7. Traducteur lmentaire LDFA - Pascal
7.1 Traducteur
7.2 Exemple
7.3 Scurit et ergonomie
8. Facteurs de qualit du logiciel
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
227
Le bon sens est la chose du monde la mieux partage...la diversit de nos opinions ne vient pas de ce que les uns
sont plus raisonnables que les autres, mais seulement de ce que nous conduisons nos penses par diverses voies,
et ne considrons pas les mmes choses. Car ce n'est pas assez d'avoir l'esprit bon, mais le principal est de
l'appliquer bien.
R Descartes Discours de la mthode, premire partie, 1637.
Le dveloppement mthodique dun logiciel passe actuellement par une dmarche de "
descente concrte " de la connaissance que lhumain a sur la problmatique du sujet, vers
laction lmentaire excute par un ordinateur. Le travail du programmeur tant alors ramen
une traduction permanente des actions humaines en actions machines (dcrites avec des
outils diffrents).
Nous pouvons en premire approximation diffrentier cette " descente concrte " en un
classement selon quatre niveaux dabstraction :
fig - schma de descente concrte
Introduction
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
228
Nous voyons que toute activit de programmation consiste transformer un problme selon
une descente graduelle de lhumain vers la machine. Ici nous avons rsum cette
dcomposition en 4 niveaux. La notion de programmation structure est une rponse ce type
de dcomposition graduelle dun problme. Lalgorithmique est la faon de dcrire cette
mthode de travail.
1. Production du logiciel
1.1 Gnie logiciel
A une certaine poque, ses dbuts, lactivit dcriture du logiciel ne reposait que sur
lefficacit personnelle du programmeur laiss pratiquement seul devant la programmation
dun problme.
De nos jours, le programmeur dispose doutils et de mthodes lui permettant de concevoir et
dcrire des logiciels. Le terme logiciel, ne dsigne pas seulement les programmes associs
telle application ou tel produit : il dsigne en plus la documentation ncessaire l'installation,
l'utilisation, au dveloppement et la maintenance de ce logiciel. Pour de gros systmes, le
temps de ralisation peut tre aussi long que le temps du dveloppement des programmes eux-
mmes.
Le gnie logiciel concerne l'ensemble des mthodes et rgles relatives la production
rationnelle des logiciels.
L'activit de dveloppement du logiciel, vu les cots qu'elle implique, est devenue une activit
conomique et doit donc tre planifie et soumise des normes sinon des attitudes
quivalentes celles que l'on a dans l'industrie pour n'importe quel produit.
C'est pourquoi dans ce cours, le mot-clef est le mot "composant logiciel" qui tient la fois
de l'activit cratrice de l'humain et du composant industriel incluant une activit discipline
et ordonne base pour certaines tches sur des outils formaliss.
D'autre part le gnie logiciel intervient lorsque le logiciel est trop grand pour que son
dveloppement puisse tre confi un seul individu ; ce qui n'est pas le cas pour des
dbutants, qui il n'est pas confi l'laboration de gros logiciels. Toutefois, il est possible de
sensibiliser le lecteur dbutant lhabitude dlaborer un logiciel dune manire systmatique
et rationnelle laide doutils simples.
1.2 Cycle de vie du logiciel
Comme il faut un temps trs important pour dvelopper un grand systme logiciel, et que
dautre part ce logiciel est prvu pour tre utilis pendant longtemps, on spare fictivement
des tapes distinctes dans ces priodes de dveloppement et dutilisation.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
229
Le modle dit de la cascade de Royce (1970) accept par tout le monde informatique est un
bon outil pour le dbutant. Sil est utilis pour de gros projets industriels, en supprimant les
recettes et les validations en fin de chaque phase, nous disposons en initiation dun cadre
mthodologique. Il se prsente alors sous forme de 8 diagrammes ou phases :
1.3 Maintenance dun logiciel
Dans beaucoup de cas le cot du logiciel correspond la majeure partie du cot total d'une
application informatique. Dans ce cot du logiciel, la maintenance a elle-mme une part
prpondrante puisqu'elle est estime de nos jours au minimum 75% du cot total du
logiciel.
La maintenance est de trois sortes :
- adaptative (sadapter un nouvel environnement...)
- corrective (corrections derreurs...)
- perfective (amliorations demandes par le client...)
1.4 Production industrielle du logiciel
La production du logiciel tant devenue une activit industrielle et donc conomique, elle
nchappe pas aux donnes conomiques classiques. On rpertorie un ensemble de
caractristiques associes un projet de dveloppement, chaque caractristique se voyant
attribuer un ratio de productivit.
Le ratio de productivit dune caractristique
Cest le rapport entre la productivit (exprime en nombre dInstructions Sources Livres, par
homme et par mois) dun projet exploitant au mieux cette caractristique, et la productivit
dun projet nexploitant pas du tout cette caractristique.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
230
Le tableau suivant est tir dune tude de B.Boehm (Revue TSI 1982 : les facteurs de cot du
logiciel):
Tableau comparatif des divers ratios de productivit (B.Boehm)
Vous aurez remarqu en observant le graphique prcdent que le facteur le plus important
n'est pas l'exprience d'un langage (erreur commise par les nophytes). Ce qui explique entre
autres arguments que l'enseignement de la programmation ne soit pas l'enseignement d'un
langage.
Il apparat que le facteur le plus coteux reste un facteur sur lequel la technologie n'a aucune
prise : l'aptitude qu'ont des individus communiquer entre eux !
Pour llaboration dun logiciel, nous allons utiliser deux dmarches classiques : la mthode
structure ou algorithmique et plus tard une extension oriente objet de cette dmarche.
2. Conception structure descendante
2.1 Critre simple dautomatisation
Un problme est automatisable (traitable par informatique) si :
- l'on peut parfaitement dfinir les donnes et les rsultats,
- l'on peut dcomposer le passage de ces donnes vers ces rsultats en une suite
d'oprations lmentaires dont chacune peut tre excute par une machine.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
231
Dans le cadre dune initiation la programmation, dans le cycle de vie dj prsent plus
haut, nous ne considrerons que les phases 2 6, en supposant que la faisabilit est acquise, et
quenfin les phases de mise en uvre et de maintenance sont mises part.
Dans cette perspective, le schma de la programmation dun problme se rduit 4 phases :
- La phase 1 de spcification utilisera les types abstraits de donnes (TAD),
- la phase 2 (correspondant aux phases 3 et 4 du cycle de vie) utilisera la mthode de
programmation algorithmique,
- la phase 3 (correspondant la phases 5 du cycle de vie) utilisera un traducteur manuel
pascal,
- la phase 4 (correspondant la phases 6 du cycle de vie) correspondra au passage sur la
machine avec vrification et jeux de tests.
Nous utiliserons un " langage algorithmique " pour la description dun algorithme rsolvant
un problme. Il sagit dun outil textuel permettant de passer de la conception humaine la
conception machine dune manire souple pour le programmeur.
Nous pouvons rsumer dans le tableau ci-dessous les tapes de travail et les outils conceptuels
utiliser lors dune telle dmarche.
ETAPES
PRATIQUES
Matriel et moyens techniques disposition
Analyse Papier, Crayon, Intelligence, Habitude.
Mise en forme de
lalgorithme
Cest laboutissement de lanalyse, esprit logique et rationnel.
Description Utilisation pratique des outils dune mthode de programmation, ici la
programmation structure.
Traduction Transfert des critures algorithmiques en langage de programmation.
Tests et mise au
point
Mise au point du programme sur des valeurs tests ou partir de
programmes spcialiss.
Excution Phase finale : le programme sexcute sans erreur.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
232
2.2 Analyse mthodique descendante
Le second [prcept], de diviser chacune des difficults que j'examinerais, en autant de parcelles qu'il se pourrait
et qu'il serait requis pour les mieux rsoudre.
R Descartes Discours de la mthode, seconde partie, 1637.
Dfinir le problme rsoudre:
expliciter les donnes
prciser: leur nature
leur domaine de variation
leurs proprits
expliciter les rsultats
prciser: leur structure
leur relations avec les donnes
fin dfinir;
Dcomposer le problme en sous-problmes;
Pour chaque sous-problmes identifi faire
si solution vidente alors crire le morceau de programme
sinon appliquer la mthode au sous-problme
fsi
fpour.
dmarche propose par J.Arsac
Cette dmarche mthodique a l'avantage de permettre d'isoler les erreurs lorsqu'on en
commet, et elles devraient tre plus rares qu'en programmation empirique (anciens
organigrammes).
Il apparat donc plusieurs niveaux de dcomposition du problme (niveaux d'abstraction
descendants). Ces niveaux permettent d'avoir une description de plus en plus dtaille du
problme et donc de se rapprocher par raffinements successifs d'une description prte la
traduction en instructions de l'ordinateur.
Afin de pouvoir dcrire la dcomposition d'un problme chaque niveau, nous avons utilis
un langage algorithmique (et non pas un langage de programmation) qui emprunte beaucoup
au langage naturel (le franais pour nous).
2.3 Analyse ascendante
Le troisime [prcept], de conduire par ordre mes penses, en commenant par les objets les plus simples et les
plus aiss connatre, pour monter peu peu, comme par degrs, jusqu' la connaissance des plus composs; et
supposant mme de l'ordre entre ceux qui ne se prcdent point naturellement les uns les autres.
R Descartes Discours de la mthode, seconde partie, 1637.
Nous essaierons de partir de lexistant (les fichiers sources dj crits sur le mme sujet) et de
reconstruire par tapes la solution. Le problme dans cette mthode est dassurer une bonne
cohrence lorsque lon rassemble les morceaux.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
233
Les mthodes objets que nous aborderons plus loin, sont un bon exemple de cette dmarche.
Nous n'en dirons pas plus dans ce paragraphe en renvoyant le lecteur intress au chapitre de
la programmation oriente objet de cours.
2.4 Programmation descendante avec retour sur un niveau
Comme partout ailleurs, une attitude appuye sur les deux dmarches est le gage dune
certaine souplesse dans le travail. Nous adopterons une dmarche danalyse essentiellement
descendante, avec la possibilit de remonter en arrire ds que le dveloppement parat trop
complexe.
Nous adopterons dans tout le reste du chapitre une telle mthode descendante (avec quelques
retours ascendants). Nous la dnommerons " programmation algorithmique ".
Nous utilisons les concepts de B.Meyer pour dcomposer un problme en niveaux logiques
puis en raffinant successivement les diffrentes tapes.
2.5 Machines abstraites et niveaux logiques
Principe :
On dcompose chacune des tapes du travail en niveaux dabstractions logiques. On suppose
en outre qu chaque niveau logique fix, il existe une machine abstraite virtuelle capable de
comprendre et dexcuter la description du problme sous la forme algorithmique en cours.
Ainsi, en descendant de labstraction vers le concret, on passe graduellement dun nonc de
problme au niveau humain un nonc du mme problme un niveau o la machine
devient capable de lexcuter.
Niveau logique Machine abstraite Enonc du problme en
0 M
0
= lhumain A
0
= langage naturel
1 M
1
= mach. Abstraite A
1
= lang.algorithmique
. . . . . . . . .
n M
n
= machine+OS A
n
= langage volu
n+1 M
n+1
= machine physique A
n+1
= langage binaire
A partir de cette dcomposition on construit un " arbre " de programmation reprsentant
graphiquement les hirarchies des machines abstraites.
Voici un exemple dutilisation de cette dmarche dans le cas de la rsolution gnrale de
lquation du second degr dans R.
Le problme se dcompose en deux sous-problmes " :
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
234
- le premier concerne la rsolution dune quation du premier degr strict
- le second est relatif la " rsolution dune quation du second degr strict " .
figure de la branche darbre 1er degr
figure de la branche darbre 2me degr
Nous avons utilis comme langage de description des tapes intermdiaires un langage
algorithmique bas sur des mots du franais. Nous le dtaillerons plus tard.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
235
3. Notion dALGORITHME
(D.E. Knuth)
Un algorithme est un ensemble de rgles qui dcrivent une squence
doprations en vue de rsoudre un problme donn bien spcifi. Un
algorithme doit rpondre aux 5 caractristiques suivantes :
- La finitude
- La prcision
- Le domaine des entres
- Le domaine des sorties
- Lexcutabilit
Notons quun algorithme exprime donc un procd squentiel (or dans la vie courante tout
nest pas ncessairement squentiel comme par exemple couter un enseignement et penser
aux prochaines vacances), et ne travaille que sur des problmes dj transforms de la phase 1
la phase 2 (la spcification). I
Il nest pas demand aux dbutants de travailler sur cette tape du processus. Cest pourquoi
la plupart des exercices de dbutant sont dj spcifis dans lnonc, ou bien leur
spcification est triviale.
Indiquons les lments de dfinition des cinq autres caractristiques demandes un
algorithme :
- Finitude : Le nombre dtapes dun algorithme doit tre fini. Le temps dexcution
pourra tre valu.
- Prcision : Chaque tape doit tre parfaitement dfinie. Toutes les actions
lmentaires doivent tre connues.
- Domaine des entres : Le champ des donnes dentre doit tre spcifi.
- Domaine des sorties : Un algorithme ayant un rsultat, il faut donner les champs
correspondants aux rsultats de sortie, ou du moins les relations entre les donnes
dentre et les donnes de sortie.
- Excutabilit : Un algorithme doit dboucher sur un programme excutable en un
temps fini et raisonnable.
On appelle environnement dun algorithme lensemble des entits utiliss par le processeur
pendant le droulement de lalgorithme.
Environnement
Dfinition
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
236
Nous allons dfinir un langage de description des algorithmes qui nous permettra de dcrire
les arbres de programmation et le fonctionnement des machines abstraites de la
programmation structure.
Voici classiquement ce que tous les auteurs utilisent comme systme de description dun
algorithme lorsquils le font avec un langage. Les deux sous-paragraphes qui suivent,
fournissent les dfinitions des lments fondamentaux dun tel langage algorithmique, le
paragraphe d'aprs construit un langage algorithmique fond sur ces lments fondamentaux.
Nous verrons que lalgorithmique est par nature plus proche de ltudiant que la machine. En
effet dans la suite du cours, ltudiant sapercevra par exemple, que les nombres rationnels ne
sont pas reprsentables simplement en machine, encore moins les nombres rels. Les langages
dimplmentations impratifs comme Pascal, Java, C# etc tant relativement pauvres cet
gard.
Ltudiant ne doit pas croire que linformatique sest rsigne ne travailler que sur les
entiers et les dcimaux, mais plutt se rendre compte quil existe une palette importante de
certains produits informatiques qui traitent plus ou moins efficacement les insuffisances des
langages classiques par exemple vis vis des rationnels (les systmes de calcul formel comme
MAPLE (tudi en Taupe),MATHEMATICA,... sont une rponse ce genre dinsuffisance).
Nous ne nous proccupons absolument pas, dans un premier temps en algorithmique, ni de la
vrification, ni du contrle, ni des restrictions dimplantation des donnes. Notre
proccupation premire est dcrire des algorithmes justes qui fonctionnent sur des donnes
justes.
3.1 Objets de base d'un langage algorithmique
Contenant
Nous appelons contenant toute cellule mmoire dune machine abstraite dun niveau fix.
Contenu
Nous appelons contenu linformation reprsente par ltat du contenant.
Atomes
Pour un contenant fix on note A lensemble de tous ses tats possibles, on dit aussi
ensemble des atomes du niveau n (niveau du contenant).
Remarques :
a) un atome de niveau n est donc un tat possible dun contenant,
b) pour un niveau logique fix, il y a un nombre datomes fini,
c) lorsque lon est au niveau machine :
- le contenant est p positions binaires( p est le nombre de bits du mot, p>1).
- A ={0,1}x....x {0,1} , p fois
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
237
Adresse fictive
Toute machine abstraite de niveau fix dispose dautant de cellules mmoires que
ncessaire. Elles sont repres par une adresse fictive ( laquelle nous navons pas accs).
Nom
Par dfinition, toute adresse nous faisons correspondre bijectivement par lopration nom,
un identificateur unique dfinissant pour lutilisateur la cellule mmoire repre par cette
adresse :
Nous dfinissons aussi un certain nombre de fonctions :
Etat : Adresse Atome (donne ltat associ une adresse)
valeur: identificateur Atome (donne ltat associ un identificateur, on dit la valeur)
contenu: Atome information (donne le contenu informationnel de latome)
signification: identificateur information (smantique de lidentificateur)
Ces 4 fonctions sont lies par le schma suivant :
3.2 Oprations sur les objets de base d'un langage algorithmique
Les parenthses dnonc en LDFA seront algol-like : nous disposerons dun marqueur du
genre debut et dun second du genre fin .
Excutant ou processeur algorithmique
Nous appelons excutant ou processeur, la partie de la machine abstraite capable de lire,
raliser, excuter des oprations sur les atomes de cette machine, ceci travers un langage
appropri.
Remarque: loprateur formel excutant dpend du temps.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
238
Instruction simple
Cest une instruction excutable en un temps fini par un processeur et elle nest pas
dcomposable en sous-tches excutables ou en autres instructions simples. Ceci est valable
un niveau fix.
Instruction compose
Cest une instruction simple, ou bien elle est dcomposable en une suite dinstructions entre
parenthses.
Composition squentielle
Si i,j,...,t reprsentent des instructions simples ou composes, nous crirons la composition
squentielle avec des " ; ". La suite dinstructions " i ; j; ...... ; t " est appele une suite
dinstructions squentielles.
Schma fonctionnel
Cest :
- soit un identificateur,
- soit un atome,
- soit une application f n variables (o n>0):
f : (identificateur)
n
identificateur
Espace dexcution
Lespace dexcution dune instruction, cest le n-uplet des n identificateurs ayant au moins
une occurrence dans linstruction (ceci un niveau fix).
Soit une instruction i
k
, lensemble E
k
des variables, ayant au moins une occurrence dans
linstruction i
k
est not : E
k
= {x
1
, x
2
, ....., x
p
} (espace d'excution de l'instruction i
k
)
Environnement
Cest lensemble des objets et des structures ncessaires lexcution dun travail donn
pour un processeur fix (niveau information).
Action
Cest lopration ou le traitement dclench par un vnement qui modifie lenvironnement
(ou bien toute modification de lenvironnement);
Action primitive
Pour un processeur donn(dune machine abstraite dun niveau fix)une action est dite
primitive, si lnonc de cette action est lui seul suffisant pour que le processeur puisse
lexcuter sans autre lments supplmentaires. Une action primitive est dcrite par une
instruction simple du processeur.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
239
Action complexe
Pour un processeur donn(dune machine abstraite dun niveau fix)une action complexe est
une action non-primitive, qui est dcomposable en actions primitives ( la fin de la phase
de conception elle pourra tre exprime soit par un module de traitement, soit par une
instruction compose).
Remarques :
- Ce qui est action primitive pour une machine abstraite de niveau n, peut devenir une
action complexe pour une machine abstraite de niveau n+1, qui est lexpression de la
prcdente un plus bas niveau (dabstraction).
- Les instructions du langage doivent tre les mmes pour tous les niveaux de machine
abstraite, sinon la programmation devient trop lourde grer.
- Tout langage de description de machine abstraite nest pas implantable sur ordinateur
(au plus partiellement sinon ce serait tout simplement un langage de programmation).
Il ne peut servir qu dcrire en partie la spcification et la conception. De plus il doit
utiliser les ides de la programmation structure descendante modulaire.
4. Un langage de description dalgorithme : LDFA
L'apprentissage d'un langage de programmation ne sert qu'aux phases 3 et 4 (traduction et excution) et ne doit
pas tre confondu avec l'utilisation d'un langage algorithmique qui prpare le travail et n'est utilis que comme
plan de travail pour la phase de traduction. En utilisant la construction d'une maison comme analogie, il suffit
de bien comprendre qu'avant de construire la maison, le chef de chantier a besoin du plan d'architecte de cette
maison pour passer la phase d'assemblage des matriaux ; il en est de mme en programmation.
Enonons un langage simple, extensible, qui est utilis dans tout le reste du document et qui
va servir dcrire les algorithmes. Nous le dnotons dans la suite du document comme LDFA
pour Langage de Description Formel dAlgorithme (terminologie non standard utilise par
l'auteur pour dnommer rapidement un langage algorithmique prcis).
4.1 Atomes du LDFA
- Les ensembles de nombres comme N,Z,Q,R (les vrais ensembles classiques des
mathmatiques et leurs structures connues).
- La grammaire mathmatique et celle du franais.
- {V,F} comme lments logiques (({V,F}, , . , v ) tant une algbre de Boole)
- Les prdicats.
- Les caractres du franais et les chanes de caractres C des machines.
Avertissement
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
240
4.2 Information en LDFA
On rappelle quune information en LDFA est obtenue par le contenu dun atome et se
construit laide de :
- la grammaire du franais et le sens commun des mots,
- les thormes et les rsultats obtenus des thories mathmatiques(le sens tant le
sens habituel donn tous les symboles),
- toutes les manipulations gnrales (algorithmes en particulier) sur les structures de
donnes.
4.3 Vocabulaire terminal du LDFA
V
T
= { < , O , lire( ) , ecrire( ) , si , tantque , alors , ftant , faire , fsi , sinon ,
sortirSi, pour , repeter , fpour , jusque , ; , entre , sortie , Algorithme , local , global ,
principal , modules , specifications , types-abstraits , debut , fin , ( , ) , [ , ] , * , + , - , / ,
, . , v }
4.4 Instructions simples du LDFA :
syntaxe : O
smantique : ne rien faire pendant un temps de base du processeur.
syntaxe : a < o
o : ae identif, et o est un schma fonctionnel.
smantique :
1) si o =identificateur alors val(a)=val(o)
2) si o est un atome alors val(a)=o
3) si o est une application / o : (id
1
,.....,id
p
) o(id
1
,.....,id
p
)
alors val(a)= o(val(id
1
),.....,val(id
p
))
o o est linterprtation de o sur lensemble des valeurs des val(id
k
)
syntaxe : lire(a) (o a e identif)
smantique : le contexte de la phrase prcise o lon lit pour "remplir" a,
sinon on indique lire(a) dans .....
Elle permet dattribuer une valeur un objet en allant lire sur un priphrique dentre et elle range cette valeur
dans lobjet.
Instruction vide
Affectation
Lecture
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
241
syntaxe : ecrire(a) (o a e identif)
smantique : le contexte de la phrase prcise o lon crit pour "voir" a,
sinon on indique ecrire(a) dans .....
Ordonne au processeur dcrire sur un priphrique (Ecran, Imprimante, Port, Fichier etc...)
syntaxe : si P alors E1 sinon E2 fsi
o P est un prdicat ou proposition fonctionnelle,
E1 et E2 sont deux instructions composes.
smantique : classique de linstruction conditionnelle, si le processeur
nest pas li au temps on peut crire :
si P alors E1 sinon O fsi = si P alors E1 fsi
Nous notons = la relation dquivalence entre instructions. Il sagit
dune quivalence smantique, ce qui signifie que les deux
instructions donnent les mmes rsultats sur le mme environnement.
syntaxe : tantque P faire E ftant
o P est un prdicat et E une instruction compose)
smantique :
tantque P faire E ftant = siP alors (E ; tantque P faire E ftant) fsi
Remarques :
Au sujet de la relation "=" qui est la notation pour lquivalence smantique en LDFA, on
considre un "programme" LDFA non pas comme une suite dinstructions, mais comme un
environnement donn avec un tat initial E0 , puis on value la modification de cet
environnement que chaque action provoque sur lui:
{E
0
} {E
1
} {E
2
} ........... {E
k
} {E
k+1
}
o action n+1 : {E
n
} {E
n+1
}.
On obtient ainsi une suite dinformations sur lenvironnement :(E
0
, E
1
, ...., E
k+1
)
Nous dirons alors que deux instructions (simples ou composes) sont smantiquement
quivalentes (notation = )si leurs actions associes sur le mme environnement de dpart
provoquent la mme modification.
A chaque instruction est associe une action sur lenvironnement, cest le rsultat qui est le
mme (mme tat de lenvironnement avant et aprs) :
Soient : Instr1 action1 (action associe Instr1),
Instr2 action2 (action associe Instr2),
Ecriture
Condition
Boucle tantque
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
242
Soient E et E deux tats de lenvironnement,
si nous avons : {E} action1 {E} et {E} action2 {E} ,alors Instr1 et Instr2 sont
smantiquement quivalentes, nous le noterons :
Instr1 = Instr2
syntaxe : repeter E jusqua P
(o P est un prdicat et E une instruction compose)
smantique :
repeter E jusqua P = E ; tantque not P faire E ftant
Exemple dquivalence entre itrations:
tantque P faire E ftant = si P alors (repeter E jusqua not P) fsi
repeter E jusqua P = E ; tantque not P faire E ftant (par dfinition)
syntaxe : pour x < a jusqua b faire E fpour
(o E est une instruction compose, x une variable, a et b des expressions
dans un ensemble fini F totalement ordonn, la relation dordre tant
note s , le successeur dun lment x dans lensemble est not Succ(x)
et son prdcesseur pred(x))
smantiques :
Cette boucle fonctionne la fois en suivant automatiquement lordre
croissant dans lensemble fini F ou en suivant automatiquement lordre
dcroissant, cela dpendra de la position respective de dpart de la borne
a et de la borne b. La variable x est appele un indice de boucle.
smantique dans le cas ordre croissant partir du tantque :
x < a ;
tantque x s succ(b)faire
E ;
x < succ(x) ;
ftant
smantique dans le cas ordre dcroissant partir du tantque :
x < a ;
tantque x > pred(b) faire
E ;
x < pred(x) ;
ftant
Boucle rpter
Boucle pour
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
243
Exemple simple :
- E = N (entiers naturels) et la relation dordre : s = infrieur ou gal dans N
- pour i < x jusqu y faire R FinPour
(ici i prendra toutes les valeurs successives dans N comprises entre x et y soient,
x+y-1 valeurs et sincrmentera de 1 chaque fois)
syntaxe : SortirSi P (o P est un prdicat ou une instruction vide)ne peut
tre utilise qu lintrieur dune itration (tantque, rpter, pour).
smantique : termine par anticipation et immdiatement lexcution de la
boucle dans laquelle linstruction SortirSi se trouve.
Exemple rcapitulatif complet
Reprenons lexemple prcdent de lquation du second degr en dcrivant dans larbre de
programmation laction de la machine abstraite de chaque niveau laide dinstructions du
langage algorithmique LDFA :
figure de la branche darbre 2me degr
Sortie de boucle
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
244
figure de la branche darbre 1
er
degr
Ecriture de l'algorithme
En relisant cet arbre selon un parcours en prordre ( il sagit de parcourir larbre en partant
de la racine et descendant toujours par le fils le plus gauche, puis ensuite de passer au fils
droit suivant etc), l'on obtient aprs avoir complt lalgorithme une criture linaire
comme suit :
Algorithme Equation
Entre: A,B,C e R3
Sortie: X1 ,X2 e R2
Local: A e R
dbut
lire(A,B,C);
Si A=0 alors { A=0 }
Si B = 0 alors
Si C = 0 alors
crire(R est solution)
Sinon { C }
crire(pas de solution)
Fsi
Sinon { B 0 }
X1 -C/B;
crire (X1)
Fsi
Sinon { A 0 }
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
245
Sinon { A 0 }
A B
2
- 4*A*C ;
Si A < 0 alors
crire(pas de solution)
Sinon { 0 }
Si A = 0 alors
X1 -B / (2*A);
crire(X1)
Sinon { 0 }
X1 (-B+sqrt(A)) / (2*A);
X2 (-B-sqrt(A)) / (2*A);
crire( X1 , X2 )
Fsi
Fsi
Fsi
FinEquation
Nous regroupons toutes les informations de conception dans un document que nous appelons
le dossier de dveloppement.
5. Le Dossier de dveloppement
Cest un document dans lequel se trouvent consigns tous les lments relatifs la construction et lcriture de
lalgorithme et du programme rsolvant le problme cherch. Nous le divisons en 5 parties.
5.1 Enonc et spcification
Enonc du problme rsolu par ce logiciel.
- Spcifications oprationnelles des abstractions de plus haut niveau du logiciel, en
exprimant celles-ci l'aide de types abstraits et de spcifications de plus bas niveau.
- Spcifications des types abstraits de donnes utiliss.
- Spcifications d'interface pour les abstractions de plus bas niveau.
On utilisera ces trois techniques de spcification de manire descendante, quitte remonter
corriger des spcifications de niveau plus haut lorsque des erreurs seront apparues dans une
spcification de plus bas niveau. Ces spcifications sont destines au niveau " concepteur de
logiciel ", plutt qu' l'utilisateur. Cette partie rassemble les dfinitions abstraites des
composants. Un utilisateur de base n'ayant priori pas consulter ce paragraphe, les termes
employs seront les plus rigoureux possibles relativement un formalisme ventuel.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
246
Analyse des besoins :
son utilit principale est de fournir l'utilisateur la description des services que lui rendra ce
logiciel. Les termes utiliss doivent tre compris par l'utilisateur.
5.2 Mthodologie
Dans ce paragraphe se situent tous les documents et les explications qui ont pu mener la
dcision de rsoudre le problme pos par la mthode que l'on a choisie. Le programmeur
dispose ici de toute latitude pour s'exprimer l'aide de texte en langue naturelle, de
reprsentation graphique, d'outils ou de supports permettant au lecteur de se faire une ide
prcise du pourquoi des choix effectus.
5.3 Environnement
Ltudiant pourra prsenter sous forme dun tableau les principales informations concernant
les donnes de son algorithme.
Exemple :
Nom genre localisation utilisation
PHT reel Entre prix hors taxe
TVA reel local TVA en %
PTTC reel sortie Prix TTC
5.4 Algorithme en LDFA
Ici se situe la description de l'algorithme propos pour rsoudre le problme propos. Il est
obtenu entre autre partir de larbre de programmation construit pendant lanalyse et la
conception. Ci-dessous le modle gnral d'un algorithme :
Algorithme XYZT;
global :
local :
entre :
sortie :
modules utiliss :
Spcifications : (TAD)
Types Abstraits de Donnes utiliss
dbut
( corps d'algorithme en LDFA)
fin XYZT.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
247
Nous verrons ailleurs ce que reprsentent les notions de TAD et
de module.
5.5 Programme en langage de programmation (Pascal par exemple)
Dans ce paragraphe nous ferons figurer la " traduction " en langage de programmation de
lalgorithme du paragraphe prcdent.
6. Trace formelle dun algorithme
Et le dernier [prcept], de faire partout des dnombrements si entiers, et des revues si gnrales, que je fusse
assur de ne rien omettre.
R Descartes Discours de la mthode, seconde partie, 1637.
Nous proposons au dbutant de vrifier l'exactitude de certaines parties de son algorithme en
utilisant un petit outil permettant l'excution formelle (c'est dire sur des valeurs algbriques
ou symboliques plutt que numriques) de son algorithme. La trace numrique et les
vrifications associes seront effectues lors de l'excution par la machine.
6.1 Espace dexcution dune instruction compose
On appelle espace dexcution dune squence ou dun bloc dinstructions i
1
...i
n
lensemble o E
k
est lespace dexcution de linstruction i
k
.
Rappelons que lon peut considrer un " programme " LDFA sous un autre point de vue : non
pas comme une suite dinstructions, mais comme un environnement donn avec un tat initial
E
0
, puis on value la modification de cet environnement que chaque instruction provoque sur
lui.
On considre les instructions i
k
comme des transformateurs denvironnement E
n
:
{E
0
} {E
1
} {E
2
} ........... {E
k
} {E
k+1
}
L'instruction i
n+1
fait alors passer l'environnement de l'tat E
n
l'tat E
n+1
.
Nous crirons ainsi : i
n+1
: {E
n
} {E
n+1
}
Ces actions dterminent alors une suite dtats de lenvironnement (E
0
,E
1
,....E
k+1
) que lon
peut observer.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
248
Cest ce point de vue qui permet dexcuter un suivi dexcution symbolique dun algorithme.
Nous le nommerons " trace formelle ".
On adoptera pour une trace formelle une disposition en tableau de lespace dexcution
comme suit :
Etats V
1
V
2
..... V
n
E
1
-- -- y
E
2
x -- y+1
La colonne Etats reprsente donc les tats successifs de lenvironnement (ou espace
dexcution) figur ici par les variables V
1
,V
2
,...,V
n
. Les contenus des cellules du tableau sont
les valeurs symboliques des variables au cours du droulement de lexcution. On peut
considrer l'image mentale suivante de la trace formelle comme tant une succession de
"photographies instantanes" de l'environnement prises aprs chaque instruction.
6.2 Exemple complet avec trace formelle
Nous traitons un exemple complet avec son dossier de dveloppement et une trace formelle.
Enonc
Calculer S= sans utiliser de formule (car l'on sait que S=(n+1)n/2 )
Spcification : flux dinformation
En Entre
Un nombre n e N
*
En Sortie
Ecrire la somme voulue S.
Mthodologie
S est la somme des termes d'une suite rcurrente :
s
i
s
0
= 0
s
i
= s
i-1
+ i
Environnement
Nom genre localisation utilisation
N Entier Entre Nombre dlments saisir
S Entier Sortie Variable de cumul pour la somme
I Entier local Gestion des boucles : compteur
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
249
Algorithme
Algorithme Somentier
N e N
*
S , I e N
2
Dbut {Somentier}
(E
0
)
Lire (N) ;
(E
1
)
S 0;
(E
2
)
I 1;
(E
3
)
TantQue I s ? ? ? faire
(E
4
)
S S+I;
(E
5
)
I I+1;
(E
6
)
FinTant;
(E
7
)
Ecrire(S);
Fin Somentier
Ceci est un algorithme incomplet dans lequel on a dj intercal les tats (E
n
) entre les
instructions. On ne sait pas exactement quel sera le test darrt de la boucle (remplac par ? ?
?), on sait seulement que cest la valeur de la variable de compteur I qui le fournira.
Utilisation de la trace formelle
Nous allons montrer laide de la trace formelle que cet algorithme fournit bien la somme des
n premiers entiers dans la variable S, relativement aux prconditions { S = 0 et i = 1}.
Nous allons donc faire de la dmonstration de programme :
Prcondition Action Postcondition
{S= 0 et i= 1} Algorithme
{ S = }
Nous pouvons avoir une hsitation quant la borne du test "TantQue I s ??? ", faut-il
s'arrter N, N-1 ou N+1 ?
Posons comme hypothse que le test s'arrte la valeur N, soit : "TantQue I s N
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
250
Excutons manuellement et pas pas lalgorithme prcdent en supposant que le test d'arrt
nest pas franchi, cest dire que lon a I > N.
Voici le dbut des rsultats de sa trace formelle dans le tableau ci-dessous :
Etats I N S
E
0
- - --
E
1
- n --
E
2
- n 0
E
3
1 n 0
E
4
=E
3
1 n 0
E
5
1 n 1
E
6
2 n 1
E
4
=E
6
2 n 1
E
5
2 n 3
E
6
3 n 3
E
4
= E
6
etc.. 3 n 3
isolons les deux premiers " tours " de boucle :
E
4
= E
6
2 n 1
E
4
= E
6
3 n 3
Nous voyons que juste avant la sortie de boucle (tat E
6
) au premier tour I=2 et S=1, au
deuxime tour I=3 et S=3 .
Nous posons lhypothse de rcurrence quau kme tour i=k+1 et S= (somme des k
premiers entiers). Nous allons utiliser lexcution formelle pas pas dun tour de boucle afin
de voir si aprs un tour de plus cette hypothse se vrifie au rang k+1 :
Etats I N S
..... ... ... ...
E
4
= E
6
k+1 n
S=
E
5
k+1 n
S= + k+1
E
6
k+2 n
S= + k+1
Or S= +k+1 = (la somme des k+1 premiers entiers).
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
251
Nous venons donc de montrer qu ltat E6 cet algorithme donne :
Etats I N S
E
6
k+1 n
S=
En particulier, lorsque k = n nous avons dans S la somme des n premiers entiers :
Etats I N S
E
6
n+1 n
S=
Nous pouvons dj crire que : n, n > 0, S =
En plus ce dernier tableau nous permet immdiatement de trouver la valeur exacte de la
variable de contrle de la boucle (ici la variable I qui vaut n+1) et donc dcrire un test
darrt de boucle juste.
On peut alors choisir comme test I<>n+1 ou bien I< n+1 etc... ou tout autre prdicat
quivalent.
Il tait possible de programmer directement cet algorithme avec les deux autres boucles
(pour... et rpeter...). Ceci est propos en exercice au lecteur.
7. Traducteur lmentaire LDFA - Java / Pascal
Nous venons de voir quun algorithme devait se traduire en langage de programmation (dit
volu). Nous fournirons ici un tableau qui sera utile ltudiant pour la traduction des
instructions algorithmiques en langage de programmation.
7.1 Traducteur
Afin de bien montrer que l'criture algorithmique est plus abstraite qu'un langage de
programmation nous donnons un tableau de traduction LDFA dans deux langages : en Pascal
de base et en Java2 restreint aux instructions seulement: ( dans le tableau, P est un prdicat et E une
instruction compose )
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
252
LDFA Java Pascal
O (instruction vide)
pas de traduction pas de traduction
debut i1 ; i2; i3; ...... ; ik fin
{ i1 ; i2; i3; ...... ; ik }
begin i1 ; i2; i3; ...... ; ik end
x a
x = a ; x := a
;
pas de traduction (ordre d'excution) ;
Si P alors E1 sinon E2 Fsi
if ( P ) E1 ; else E2 ;
( attention, pas de fermeture !)
if P then E1 else E2
( attention, pas de fermeture !)
Tantque P faire E Ftant
while ( P ) E ;
( attention, pas de fermeture)
while P do E
( attention, pas de fermeture)
rpeter E jusqu P
do E ; while ( ! P ) ; repeat E until P
lire (x1,x2,x3......,xn )
System.in.read( ) ;
System.in.readln( ) ;
read(fichier,x1,x2,x3......,xn )
readln(x1,x2,x3......,xn )
Get(fichier)
ecrire (x1,x2,x3......,xn )
System.in.print( ) ;
System.in. println( ) ;
write(fichier,x1,x2,x3......,xn )
writeln(x1,x2,x3......,xn )
Put(fichier)
pour x a jusqu b faire
E
Fpour
for (int x= a; x <= b; x++)
E ;
for x:=a to b do E (croissant)
for x:=a downto b do E (dcroissant)
( attention, pas de fermeture)
SortirSi P
if ( P ) break ; if P then Break
Ce tableau de traduction permet dj dcrire trs rapidement des programmes Pascal et Java
simples partir dalgorithmes tudis et crits.
7.2 Exemple
En appliquant le traducteur lalgorithme de lquation du second degr nous obtenons le
programme Pascal suivant :
programequation;
var
A,B,C:real;
X1,X2:real;
Delta:real;
begin
readln(A,B,C);
if A = 0 then {A=0}
if B = 0 then
if C = 0 then
writeln('R est solution')
else
writeln('pas de solution')
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
253
else
begin
X1 := - C/B;
writeln('x=',X1)
end
else
begin
Delta := B*B-4*A*C;
if Delta < 0 then
writeln('pas de solution')
else
if Delta=0 then
begin
X1 := -B/(2*A);
writeln('x=',X1)
end
else
begin
X1 := (-B + Sqrt(Delta)) / (2*A);
X2 := (-B - Sqrt(Delta)) / (2*A);
writeln('x1=',X1,'x2=',X2)
end
end
end.
En appliquant le traducteur Java2 ce mme algorithme de lquation du second degr, nous
obtenons le squelette de programme Java2 suivant :
if (a ==0)
if (b ==0)
if (c ==0)
System.out.println("tout reel est solution") ;
else
System.out.println("il n'y a pas de solution") ;
else {
x = -c/b ;
System.out.println("la solution est " + x) ;
}
else {
delta = b*b -4*a*c ;
if (delta <0)
System.out.println("il n'y a pas de solution dans les reels") ;
else
if (delta == 0) {
x1 = -b / (2*a) ;
System.out.println("il y a une solution double : "+x1) ;
}
else {
x1 = (-b + Math.sqrt(delta)) / (2*a) ;
x2 = (-b - Math.sqrt(delta)) / (2*a) ;
System.out.println("il y deux solutions gales a "+x1+" et " + x2) ;
}
} etc
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
254
7.3 Scurit et ergonomie
Lutilisation du traducteur manuel LDFA > Pascal fournit une version prliminaire de
programme pascal fonctionnant sur des donnes correctes sans aucune prsentation.
Il appartient au programmeur de complter dans un deuxime temps la partie scurit associe
aux contraintes du domaine de dfinition des variables et aux contraintes matrielles
dimplantation. Enfin, dans un troisime temps, lergonomie (forme de lchange
dinformation entre le programme et le futur utilisateur) sera envisage et programme.
Voyons sur lexemple de la somme des n premiers entiers dj cit plus haut, comment ces
trois tapes sarticulent .
Etape de traduction-somme des n premiers entiers
Texte final de lalgorithme de dpart : Texte de sa traduction en pascal :
Algorithme Somentier
N e N
*
S , I e N
2
Dbut {Somentier}
Lire (N) ;
S 0;
I 1;
TantQue I < N+1 faire
S S+I;
I I+1;
FinTant;
Ecrire(S);
Fin Somentier
programSomentier ;
var N : integer ;
S,I : integer ;
begin
readln(N) ;
S :=0 ;
I :=1 ;
while I < N+1 do
begin
S := S +I;
I := I+1;
end;
writeln(S)
end.
Etape de scurisation-somme des n premiers entiers
Scurit due aux domaines de dfinition des donnes
La traduction ne permet pas dcrire les domaines de dfinition des variables : en loccurrence
ici la variable N eN
*
est traduite par " var N : integer ", or le type prdfini integer est un
sous-ensemble des entiers relatifs Z, il est donc ncessaire dliminer les entiers ngatifs ou
nuls comme choix possible.
Ds que lutilisateur aura entr son nombre, le programme devra tester lappartenance au bon
intervalle afin de protger la partie de code, par exemple avec une instruction de condition :
if N > 0 then begin
// code protg
end
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
255
Protection programme dans les pointills en dessous dans le cadre de droite :
programSomentier ; programSomentier ;
var N : integer ;
S,I : integer ;
var N : integer ;
S,I : integer ;
begin
readln(N) ;
begin
readln(N) ;
if N > 0 then begin
S :=0 ;
I :=1 ;
S :=0 ;
I :=1 ;
while I < N+1 dobegin
S := S + I;
while I < N+1 do begin
S := S + I;
I := I+1;
end;
writeln(S)
I := I+1;
end;
writeln(S)
end
end. end.
Scurit due aux contraintes dimplantation
Si nous excutons ce programme pour la valeur N=500, la valeur fournie en sortie est " -5822
" sur un pascal 16 bits comme TP-pascal, le rsultat n'est pas correct. Nous sommes
confronts au problme de la reprsentation des entiers machines dj cit. Ici le type integer
est restreint lintervalle [-32768,+32767] ; il y a manifestement dpassement de capacit
(overflow) et le systme a allgrement continu les calculs malgr ce dpassement. En effet,
la somme vaut 500*501/2 soit 125250, cette valeur nappartient pas lintervalle des integer.
Le programmeur doit donc remdier ce problme par un effort personnel de scurisation de
son programme en nautorisant les calculs que pour des valeurs valides offrant un maximum
de scurit.
Ici la variable S contient la somme , nous savons que = k(k+1)/2, donc il suffira de
rsoudre dans N linquation k(k+1)/2 s 32767 o n est linconnue. Lunique solution
positive a pour partie entire 255, qui est la valeur maximale avant dpassement de capacit.
Donc il suffit de protger le code par un test supplmentaire sur la variable N :
if (N > 0) and (N < 256) then begin
S :=0 ;
I :=1 ;
while I< N+1 do begin
S := S +I;
I := I+1;
end;
writeln(S)
end
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
256
En vrifiant sur lexcution, nous trouvons que S = 32640 pour N = 255. Ce qui nous donne la
version suivante du programme :
program Somentier ;
var N : integer ;
S , I : integer ;
begin
readln(N) ;
if (N > 0) and (N < 256) then begin
S :=0 ;
I :=1 ;
while I< N+1 do begin
S := S +I;
I := I+1;
end;
writeln(S)
end
end.
Etape dergonomie-somme des n premiers entiers
Dans cet exemple, linformation changer avec lutilisateur est trs simple et ne ncessite
pas une interface spciale. Il sagira de lui prciser les contraintes dentre et de lui prsenter
dune manire claire le rsultat.
program Somentier ;
var N : integer ;
S , I : integer ;
begin
Write(Entrez un entier entre 0 et 255) ;
readln(N) ;
if (N > 0) and (N < 256) then begin
S :=0 ;
I :=1 ;
while I< N+1 do begin
S := S +I;
I := I+1;
end;
writeln(la somme des ,N, premiers entiers vaut ,S)
end
else
writeln(Calcul impossible ! !)
end.
Vous remarquerez que les adjonctions supplmentaires de code (en italique) dans le
programme final se montent environ 50% du total du code crit, car un logiciel nest pas
uniquement un algorithme traduit.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
257
En continuant dappliquer le principe de la programmation structure, il est bon de bien
sparer lors du dveloppement la partie algorithmique des parties scurit et ergonomie. Le
programmeur dbutant y gagnera en clart dans sa mthode de travail.
8. Facteurs de qualit du logiciel
B.Meyer et G.Booch
Un utilisateur, lorsquil achte un produit comme un appareil lectro- mnager ou une
voiture, attend de son acquisition quelle possde un certain nombre de qualits (fiabilit,
durabilit, efficacit, ...). Il en est de mme avec un logiciel.
Voici une liste minimale de critres de qualit du logiciel (propose B.Meyer, G.Booch):
Correction Robustesse Extensibilit
Rutilisabilit Compatibilit Efficacit
Portabilit Vrificabilit Intgrit
Facilit utilisation Modularit Lisibilit
Abstraction
Reprenons les dfinitions communment admises par ces deux auteurs sur ces facteurs de
qualit.
La correction est la qualit qu'un logiciel a de respecter les
spcifications qui ont t poses.
La robustesse est la qualit qu'un logiciel a de fonctionner en
se protgeant des conditions de dysfonctionnement.
L'extensibilit est la qualit qu'un logiciel a daccepter des
modifications dans les spcifications et des adjonctions
nouvelles.
La rutilisabilit est la qualit qu'un logiciel a de pouvoir tre
intgr totalement ou partiellement sans rcriture dans un
nouveau code.
La compatibilit est la qualit qu'un logiciel a de pouvoir tre
utilis avec d'autres logiciels sans autre effort de conversion
des donnes par exemple.
Constat
Correction
Robustesse
Extensibilit
Rutilisabilit
Compatibilit
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
258
L'efficacit est la qualit qu'un logiciel a de bien utiliser les
ressources.
La portabilit est la qualit qu'un logiciel a d'tre facilement
transfr sur de nombreux matriels, et insrable dans des
environnements logiciels diffrents.
La vrificabilit est la qualit qu'un logiciel a de se plier la
dtection des fautes, au traage pendant les phases de validation
et de test.
L'intgrit est la qualit qu'un logiciel a de protger son code et
ses donnes contre des accs non prvus.
La facilit d'utilisation est la qualit qu'un logiciel a de pouvoir
tre appris, utilis, interfac, de voir ses rsultats rapidement
compris, de pouvoir rcuprer des erreurs courantes.
La lisibilit est la qualit qu'un logiciel a d'tre lu par un tre
humain.
La modularit est la qualit qu'un logiciel a d'tre
dcomposable en lments indpendants les uns des autres et
rpondants un certain nombre de critres et de principes.
L'abstraction est la qualit qu'un logiciel a de sattacher
dcrire les oprations sur les donnes et ne manipuler ces
donnes qu travers ces oprations.
La production de logiciels de qualit nest pas une spcificit des professionnels de la
programmation ; cest un tat desprit induit par les mthodes du gnie logiciel. Le dbutant
peut, et nous le verrons par la suite, construire des logiciels ayant des " qualits " sans avoir
fournir defforts supplmentaires.
Bien au contraire la ralit a montr que les tudiants " bricoleurs " passaient finalement plus
de temps " bidouiller " un programme que lorsquils dcidaient duser de mthode de
travail. Une amlioration de la qualit gnrale du logiciel en est toujours le rsultat.
Efficacit
Portabilit
Vrificabilit
Intgrit
Facilit
Lisibilit
Modularit
Abstraction
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
259
Machines abstraites : exemple
Traitement descendant modulaire d'un exemple complet
Objectif : dvelopper un exemple simple de construction d'une machine abstraite par
dcomposition descendante sur 4 niveaux.
ENONCE
On donne une liste de n noms (composs de lettres uniquement). Extrayez ceux qui sont le
premier et le dernier par ordre alphabtique. Ecrire un programme Pascal effectuant cette
opration.
SPECIFICATIONS :(il s'agit d'claircir certaines dcisions)
Plan:
Objets utiliss,
machine abstraite,
spcification de donnes.
Identification Signification
( Liste , << ) Liste est un ensemble fini de noms o << est une relation
d'ordre total
Noms Ensemble de tous les noms possibles (chacun est
constitu de lettres)
lment Fonction fournissant le kime lment de la liste :
lment : N* x Liste Liste
Grand Un lment de l'ensemble Noms :
Grand e Noms
Petit Un lment de l'ensemble Noms :
Petit e Noms
Long Fonction fournissant le nombre dlments de la liste :
Long : Liste N*
Objets utiliss au niveau 1
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
260
(description de haut niveau d'abstraction de l'algorithme choisi)
Grand lment ( 1 , Liste) ;
Petit lment ( 1 , Liste) ;
Pour indice 2 jusqu Long (Liste) faire
Si Grand << lment (indice, Liste) alors
Grand lment (indice, Liste)
fsi ;
Si lment (indice ,Liste) << Petit alors
Petit lment (indice, Liste)
fsi
Fpour ;
{Grand = le dernier et Petit = le premier }
Identification Signification
Noms Un ensemble de caractres
( Liste , << ) Liste est un ensemble fini muni d'une relation d'ordre
total <<
lment Fonction lment : N* x Liste Liste
(k, Liste) lment (k, Liste) e Liste
Long Fonction fournissant le nombre dlments de la liste :
Long : Liste N*
Liste Long (Liste) = n
Nous avons ici une spcification abstraite de haut niveau. Il est impratif de prendre des
dcisions sur les structures de donnes qui vont tre utilises. Nous allons envisager le cas le
plus simple : celui o la structure choisie pour reprsenter la liste est un tableau.
Reprise des objets abstraits en les exprimant de la faon suivante :
Cas A o la version pascal contient dj les outils de chanes
- Liste = Tableau
- lment (i, Liste) = Liste[i]
- Long(Liste) = n , taille du tableau
- Noms : Type string
- << : s (relation de comparaison lexicographique sur les chanes)
Machine abstraite de niveau 1
Les donnes au niveau 1
Les donnes au niveau 2
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
261
Nous continuons descendre dans les niveaux dabstraction. Nous devons prendre des
dcisions sur le langage-cible. Il est dit dans l'nonc que ce doit tre Pascal, mais lequel ?
Nous avons choisi dans ce premier cas, une version simple en prenant par exemple comme
dialecte deux descendants de l'UCSD-Pascal, savoir Think Pascal (Mac) ou Borland Pascal-
Delphi (Windows-Linux) qui contiennent en prdfini le type de chane de caractres.
Ces spcifications de donnes tant tablies, la machine prcdente devient :
cas A
Algorithme EXTRAIT0
Global : n e N* , Long_mot e N*
Local : indice e N*, ( Grand , Petit ) e Noms
2
Spcification:
Noms = Type string prdfini par une version dimplmentation du pascal.
Liste = Tableau de Nom, de Taille n e N* fixe.
Dbut
Grand Liste[1] ;
Petit Liste[1] ;
Pour indice 2 jusqu n faire
Si Grand < Liste[indice] alors Grand Liste[indice] fsi ;
Si Liste[indice] < Petit alors Petit Liste[indice] fsi
Fpour ;
Fin_EXTRAIT0
Cet algorithme se traduit immdiatement en pascal. Nous voyons donc quil nous a t possible dcrire ce
petit programme en descendant uniquement sur 2 niveaux de spcifications.
Quen est-il lorsque lon travaille avec un autre langage cible (nous allons juste utiliser une
version diffrente du mme langage cible) ? Nous allons voir que nous devrons descendre
alors plus loin dans les spcifications et dvelopper plus de code c'est l'objectif de la suite de
ce document.
Cas B o la version pascal ne contient pas les outils de chanes
Reprenons partiellement la mme spcification de donnes par un tableau de taille n pour la
Liste, mais supposons que le langage-cible soit du Pascal ISO, dans lequel le type string
nexiste pas.
Machine abstraite de niveau 2
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
262
cas B
Cas B o la version pascal ne contient pas d'outils de chanes
- Noms : Nous choisissons, afin de ne pas nous perdre en complexits inutiles, de spcifier
la l'ensemble des caractres par un tableau de caractres : notons le Tchar
- Liste = Tableau de Tchar
- lment (i, Liste) = Liste[i]
- Long(Liste) = n , taille du tableau .
- << : CMP (oprateur de relation de comparaison sur les Tchar)
cas B
Ces choix de spcification induisent un choix de dveloppement d'une machine abstraite
spcifique la relation d'ordre << , qui n'est pas un oprateur simple du langage : nous avons
dnot la machine par le nom CMP.
Noms = Tchar
Taille de Tchar = n
ch1 e Tchar , ch2 e Tchar
Spcification de loprateur CMP de comparaison de chanes :
CMP : Tchar x Tchar { Vrai , Faux }
CMP (ch1,ch2) = Vrai ssi (ch1 < ch2) ou (ch1 = ch2)
CMP (ch1,ch2) = Faux ssi ch2 < ch1
ch1 e Noms,
ch2 e Noms
Descendons dans les spcifications plus concrtes de la machine abstraite de comparaison,
spcifions d'une manire plus dtaille, les donnes Noms et Liste de la machine abstraite
CMP, en rpondant aux deux questions ci-dessous :
Noms = Tableau de caractres not Tchar , comment est-il reprsent ?
Liste = Tableau de Tchar , comment est-il reprsent ?
Les donnes au niveau 2
Machine abstraite CMP
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
263
cas B
Un nom Noms :
1 2 Long_mot
Noms = Tableau de caractres
Noms [i] = le caractre de rang i-1
Attributs :
- Taille = Long_mot
- caractre spcial = #
Une liste de noms Liste :
Liste = Tableau de noms
Liste[i] = le Noms de rang i
Attribut :
Taille = n
On dispose d'une relation d'ordre sur les caractres (ordre ASCII) note s .
cas B
Dcrivons une premire version de CMP en tenant compte des spcifications de donnes
prcdentes.
Tantque (les caractres lus de ch1 et de ch2 sont les mmes)
et (ch1 non entirement explor) et (ch2 non entirement explor) faire
passer au caractre lu suivant dans ch1 ;
passer au caractre lu suivant dans ch2 ;
Ftant ;
Si (ch1 et ch2 finis en mme temps) alors ch1=ch2 fsi ;
Si (ch1 fini avant ch2) ou (car_Lu de ch1 < car_Lu de ch2) alors ch1 < ch2 fsi ;
Si (ch2 fini avant ch1) ou (car_Lu de ch2 < car_Lu de ch1) alors ch2 < ch1 fsi ;
Descendons plus bas dans les niveaux dabstraction.
Les donnes au niveau 3
Machine CMP de niveau 3
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
264
cas B
Notre travail va consister expliciter, l'aide des structures de donnes choisies les phrases
de haut niveau d'abstraction de la spcification de niveau 3 de CMP (en italique le niveau 3,
en gras le niveau 4):
spcification de niveau 3 de CMP spcification de niveau 4 de CMP
car_Lu de ch1 ch1[i] (ime caractre de ch1)
car_Lu de ch2 ch2[k] (kme caractre de ch2)
ch1 fini ou entirement explor ch1[i] = #
Ch2 fini ou entirement explor ch2[k] = #
les caractres lus de ch1 et de ch2 sont les mmes ch1[i] = ch2[i]
caractre suivant de ch1 , ch2 Si caractre actuel = ch1[k] alors
caractre suivant = ch1[k+1] ,
idem pour ch2
La spcification oprationnelle de niveau 4 de CMP devient alors :
Tantque (ch1[k] = ch2[k] ) et ( ch1[k] = # ) et ( ch2[k] = # ) faire
k k+1
Ftant ;
Si ( ch1[k] = # ) et ( ch2[k] = # ) alors CMP Vrai fsi ;
Si ( ch1[k] = # ) ou (ch1[k] < ch2[k] ) alors CMP Vrai fsi ;
Si ( ch2[k] = # ) ou (ch2[k] < ch1[k] ) alors CMP Faux fsi ;
Il faut prvoir d'initialiser le processus au premier caractre k=1 d'o maintenant une
spcification de l'algorithme :
Algorithme CMP
Local : k e N*
entre : ( ch1 , ch2 ) e Noms
2
sortie : CMP e { Vrai, Faux }
Spcification:
Noms = Tableau de Taille Long_mot fixe disposant d'un caractre de fin (#)
Dbut
k 1 ;
Tantque(ch1[k] = ch2[k]) et (ch1[k] = # ) et (ch2[k] = # ) faire
k k+1
Ftant ;
Si( ch1[k] = '#' ) et ( ch2[k] = '#' ) alors CMP Vrai fsi ;
Si ( ch1[k] = '#' ) ou (ch1[k] < ch2[k] ) alors CMP Vrai fsi ;
Si ( ch2[k] = '#' ) ou (ch2[k] < ch1[k] ) alors CMP Faux fsi ;
Fin_CMP.
Machine CMP de niveau 4
CMP
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
265
Puis en intgrant la machine abstraite CMP de niveau 4 avec les spcifications de TAD
dcrites prcdemment, le tout dans la spcification de niveau 3 de l'algorithme choisi, nous
obtenons l'algorithme final suivant :
cas B
Algorithme EXTRAIT1
Global : n e N* , Long_mot e N*
Local : indice e N*, ( Grand , Petit ) e Noms
2
module utilis :
Spcification:
Noms = Tableau de caractres, de Taille Long_mot fixe disposant d'un attribut marqueur
de fin, qui est le caractre spcial # .
Liste = Tableau de Noms, de Taille n e N* fixe.
TAD utiliss:
- Tableau de caractre de dimension 1.
- Tableau de Noms de dimension 1.
Dbut
Grand Liste[1] ;
Petit Liste[1] ;
Pour indice 2 jusqu n faire
Si CMP(Grand , Liste[indice] ) alors Grand Liste[indice] fsi ;
Si CMP(Liste[indice] , Petit ) alors Petit Liste[indice] fsi
Fpour ;
Fin_EXTRAIT1.
Voici une traduction possible en Pascal de cet algorithme.
Program EXTRAIT1;
Const
Taille = 5;
Long_mot = 20;
Type
Nom = array[1..Taille] of Char;
List_noms = array[1..Long_mot ] of Nom;
Var
Liste : List_noms;
indice : integer;
Grand,Petit : Nom;
Algorithme EXTRAIT1 niveau 4
CMP
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
266
function CMP (ch1,ch2:Nom):Boolean;
var
k : integer;
begin
k:=1
While (ch1[k]=ch2[k])and(ch1[k]<'#')and(ch2[k]<'#') do k:=k+1;
if (ch1[k]='#')and(ch2[k]='#') then result :=True;
if (ch1[k]='#')or(ch1[k]<ch2[k]) then result :=True;
if (ch2[k]='#')or(ch2[k]<ch1[k]) then result :=False;
end;{CMP}
procedure INIT_Liste;
begin
{initialise la liste des noms termins par des #}
end;
procedure ECRIRE_Nom (name:Nom);
begin
{crit sur une mme ligne les caractres qui composent la variable name, sans le #}
end;{ECRIRE_Nom}
Begin{EXTRAIT}
INIT_Liste;
Grand:=Liste[1];
Petit:=Liste[1];
for indice:=2 to taille do
begin
if CMP(Liste[indice],Petit) then Petit := Liste[indice];
if CMP(Grand,Liste[indice]) then Grand := Liste[indice];
end;
write('Le premier est : ');
ECRIRE_Nom(Petit);
write('Le dernier est : ');
ECRIRE_Nom(Grand);
End.{ EXTRAIT }
Le lecteur comprendra partir de cet exemple que les langages de programmation sont trs nombreux et
que le choix dun langage pour dvelopper la solution dun problme est un lment important.
Autres versions possibles partir de CMP
La version dimplantation de CMP du niveau 4 a t conue sur une structure de donnes
tableau termine par une sentinelle (le caractre #). Elle a t implante par une fonction en
pascal.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
267
Il est possible de rcrire dautres version dimplantation de cette mme machine CMP avec
des structures de donnes diffrentes comme un tableau avec un attribut de longueur ou bien
une structure liste dynamique :
Fig - schma des trois reprsentations des donnes (a
1
, , a
n
)
Nous engageons le lecteur crire chaque fois lalgorithme associ et le traduire en un
programme pascal.
Nous donnons ci-aprs, au lecteur les trois versions dimplantation en pascal de la fonction
CMP associe (sentinelle, pointeur, attribut).
CMP
programme avec sentinelle
function CMP(ch1,ch2:Nom):Boolean;
var
k : integer;
begin
k:=1
While (ch1[k]=ch2[k])
and(ch1[k]<'#')
and(ch2[k]<'#') do
k:=k+1;
if (ch1[k]='#')and(ch2[k]='#') then
result :=True;
if (ch1[k]='#')or(ch1[k]<ch2[k]) then
result :=True;
if (ch2[k]='#')or(ch2[k]<ch1[k]) then
result :=False;
end;{CMP}
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
268
CMP
programme avec pointeur
type pchaine=^chaine;
chaine=record
car:char;
suiv:pchaine;
end;
function CMP(ch1,ch2:Nom):Boolean;
begin
while ((ch1^.car=ch2^.car)
and (ch1^.suiv<nil)
and (ch2^.suiv<nil)) do
begin
ch1:=ch1^.suiv;
ch2:=ch2^.suiv;
end;
if ((ch1^.suiv=nil) and (ch2^.suiv=nil)) then
CMP:=true;
if (((ch1^.suiv=nil) and (ch2^.suiv<nil))
or (ch1^.car<ch2^.car)) then result:=true;
if (((ch2^.suiv=nil) and (ch1^.suiv<nil))
or (ch1^.carch2^.car)) then result:=false;
end;{CMP}
CMP
programme avec attribut
const MaxCar=1000;
type inter=0..MaxCar;
chaine=record
long:integer;
car:array[1..MaxCar] of char;
end;
function CMP(ch1,ch2:Nom):Boolean;
var n:integer;
begin
n:=1;
while (ch1.car[n]=ch2.car[n])
and ((n<n1)
and (n<n2)) do
n:=n+1;
if ((n=ch1.long) and (n=ch2.long)) then
result :=true;
if (((n=ch1.long) and (n<ch2.long))
or (ch1.car[n]<ch2.car[n])) then
result:=true;
if((n=ch2.long) and (n<ch1.long))
or (ch1.car[n]ch2.car[n]) then
result:=false;
end;{CMP}
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
269
3.2 : Modularit
Plan du chapitre:
1. La modularit
1.1 Notion de module
1.2 Critres principaux de modularit
La dcomposabilit modulaire
La composition modulaire
La continuit modulaire
La comprhension modulaire
La protection modulaire
1.3 Prceptes minimaux de construction modulaire
Interface de donnes minimale
Couplage minimal
Interfaces explicites
Information publique et prive
2. La modularit par les unit en pascal UCSD
2.1 Partie " public " dune UNIT : " Interface "
2.2 Partie " prive " dune UNIT : " Implementation "
2.3 Partie initialisation dune UNIT
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
270
1. Modularit (selon B.Meyer)
1.1 Notion de module
Le mot MODULE est un des mots les plus employs en programmation moderne. Nous
allons expliquer ici ce que l'on demande, une mthode de construction modulaire de
logiciels, de possder comme proprits, puis nous verrons comment dans certaines
extensions de Pascal sur micro-ordinateur (Pascal, Delphi), cette notion de module se
trouve implante.
B.Meyer est lun des principaux auteurs avec G.Booch qui ont le plus travaill sur cette
notion. Le premier a implant ses ides dans le langage orient objet " Eiffel ", le second a
utilis la modularit du langage Ada pour introduire le concept dobjet qui a t la base de
mthodes de conception orientes objet : OOD, HOOD,UML...
Nous nous appuyons ici sur les concepts noncs par B.Meyer fonds sur 5 critres et 6
principes relativement une mthodologie danalyse de type modulaire. Une dmarche (et
donc le logiciel construit qui en dcoule) est dite modulaire si elle respecte au moins les
concepts ci-aprs.
1.2 Critres principaux de modularit
Les 5 principes retenus :
- La dcomposabilit modulaire
- La composition modulaire
- La continuit modulaire
- La comprhension modulaire
- La protection modulaire
Dfinitions et ralisations en Pascal de ces cinq principes
La dcomposabilit modulaire :
capacit de dcomposer un problme en sous-problmes, semblable la mthode structure
descendante.
Ralisation de ce critre en Pascal :
La hirarchie descendante des procdures et des fonctions.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
271
Illustration de la dcomposabilit en Pascal :
La composition modulaire :
capacit de recombinaison et de ragencement de modules crits, semblable la partie
ascendante de la programmation structure.
Ralisation de ce critre en Pascal :
N'existe pas en Pascal standard, toutefois la notion d'UNIT en Pascal UCSD (dont le
Delphi est un descendant) et de Library en sont deux implantations partielles.
Illustration de la composition en Pascal :
La continuit modulaire :
capacit rduire limpact de changements dans les spcifications un minimum de
modules lis entre eux, et mieux un seul module.
Ralisation de ce critre en Pascal :
Partiellement ; le cas particulier des constantes symboliques en Pascal standard, au
paragraphe const, montre lintrt de ce critre.
Exemple : const n=10 ;
....
for i :=1 to n do ....
...
if T1 < n then ....
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
272
Il suffit de changer la ligne const n=10 pour modifier automatiquement les instructions o
intervient la constante n, sans avoir les rcrire toutes. Cette pratique en Pascal est trs utile
en particulier lorsquil sagit de compenser le dfaut dans la continuit modulaire, apport par
la notion de tableau statique dont les bornes doivent tre connues lavance.
La comprhension modulaire :
capacit linterprtation par un programmeur du fonctionnement dun module ou dun
ensemble de modules lis, sans avoir connatre tout le logiciel.
Ralisation de ce critre en Pascal :
Partiellement la charge du programmeur en crivant des procdures et des fonctions qui
sappellent le moins possible. Chaque procdure ou fonction doit tre ddie une tche
autonome.
Plus efficace dans Delphi grce la notion dUNIT.
La protection modulaire :
capacit limiter les effets produits par des incidents lors de lexcution un nombre
minimal de modules lis entre eux, mieux un seul module.
Ralisation de ce critre en Pascal :
Correcte en Pascal grce au contrle des types et des bornes des paramtres d'entres ou de
sorties d'une procdure ou d'une fonction. Les variables locales permettent de restreindre la
porte dun incident.
Les pointeurs en Pascal
Le type pointeur met fortement en dfaut ce critre, car sa gestion mmoire est de bas
niveau et donc confie au programmeur ; les pointeurs ne respectent mme pas la notion
de variable locale!
En gnral le passage par adresse met en dfaut le principe de protection modulaire.
1.3 Prceptes minimaux de construction modulaire
Etant dbutants, nous utiliserons quatre des six prceptes noncs par B.Meyer. Ils sont
essentiels et sont adopts par tous ceux qui pratiquent des mthodes de programmation
modulaire :
- Interface de donnes minimale
- Couplage minimal
- Interfaces explicites
- Information publique et prive
Attention
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
273
Prcepte 1 : Interface de donnes minimale
Un module fix doit ne communiquer quavec un nombre " minimum " dautres modules du
logiciel. Lobjectif est de minimiser le nombre d'interconnexions entre les modules. Le
graphe tablissant les liaisons entre les modules est not " graphe de dpendance ". Il doit
tre le moins maill possible. La situation est semblable celle que nous avons rencontr
lors de la description des diffrentes topologies des rseaux dordinateurs : les liaisons les
plus simples sont les liaisons en toile, les plus complexes (donc ici dconseilles) sont les
liaisons totalement mailles.
L'intrt de ce prcepte est de garantir un meilleur respect des critres de continuit et de
protection modulaire. Les effets d'une modification du code source ou d'une erreur durant
l'excution dans un module peuvent se propager un nombre plus ou moins important de
modules en suivant le graphe de liaison. Un dbutant optera pour une architecture de liaison
simple, ce qui induira une construction contraignante du logiciel. Loptimum est dfini par le
programmeur avec lhabitude de la programmation.
Ralisation de ce prcept en Pascal :
Le graphe de dpendance des procdures et des fonctions sera arborescent ou en toile.
Prcepte 2 : Couplage minimal
Lorsque deux modules communiquent entre eux, lchange dinformation doit tre
minimal. Ce prcepte ne fait pas double emploi avec le prcdent. Il s'agit de minimiser
la taille des interconnexions entre modules et non leur nombre comme dans le prcepte
prcdent.
Ralisation de ce prcept en Pascal :
En gnral, nous avons aussi un couplage fort lorsqu'on introduit toutes les variables
comme globales (donc viter, ce qui se produit au stade du dbutant). D'autre part la
notion de visibilit dans les blocs imbriqus et la porte des variables Pascal donne accs
des donnes qui ne sont pas toutes utiles au niveau le plus bas.
Prcepte 3 : Interfaces explicites
Lorsque deux modules M1 et M2 communiquent, lchange dinformation doit tre
lisible explicitement dans lun des deux ou dans les deux modules.
Ralisation de ce prcept en Pascal :
Lutilisation des donnes globales ou de la notion de visibilit nuit aussi ce principe. Le
risque de battre en brche le prcepte des interfaces explicites est alors de conduire des
accs de donnes injustifis (problme classique des effets de bord, o lon utilise
implicitement dans un bloc une donne visible mais non dclare dans ce bloc).
Prcepte 4 : Information publique et prive
Toute information dans un module doit tre rpartie en deux catgories : linformation
prive et linformation publique.
Ce prcepte permet de modifier la partie prive sans que les clients (modules utilisant ce
module) aient supporter un quelconque problme cause de modifications ou de
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
274
changements. Plus la partie publique est petite, plus on a de chances que des changements
n'aient que peu d'effet sur les clients du module.
- La partie publique doit tre la description des oprations ou du fonctionnement du
module.
- La partie prive contient limplantation des oprateurs et tout ce qui s'y rattache.
Ralisation de ce prcept en Pascal :
Le Pascal standard ne permet absolument pas de respecter ce principe dans le cadre gnral.
Delphi, avec la notion d'UNIT cotient une approche partielle mais utile de ce principe. Les
prmisses de cette approche existent malgr tout dans les notions de variables et de
procdures locales une procdure. La notion de classe en Delphi implante compltement
ce principe.
Enfin et pour mmoire nous citerons lexistence du prcepte douverture-fermeture et du prcepte dunits
linguistiques.
2. La modularit par les Unit avec Delphi
La notion de UNIT a t introduite en Pascal UCSD anctre de Delphi
Rappelons que Delphi et les versions de compilateurs libres gratuit comme FreePascal
compiler, Obron etc... prsentes sur Internet fonctionnant sur les micro-ordinateurs type PC,
ainsi que le Think Pascal de Symantec fonctionnant sur les MacIntosh dApple, sont tous une
extension du Pascal UCSD. Il est donc possible sur du matriel courant dutiliser la notion
dUNIT simulant le premier niveau du concept de module.
Cet lment reprsente une unit compilable sparment de tout programme et stockable en
bibliothque. Une Unit comporte une partie " public " et une partie " priv ". Elle implante
donc lide de module et tend la notion de bloc (procdure ou fonction) en Pascal.
Syntaxe :
Exemple :
Unit Truc;
<partie public>
<partie prive>
<initialisation>
end.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
275
2.1 Partie " public " dune UNIT : " Interface "
Correspond exactement la partie publique du module reprsent par la UNIT. Cette partie
dcrit les en-ttes des procdures et des fonctions publiques utilisables par les clients. Les
clients peuvent tre soit dautres procdures Pascal, des programmes Delphi ou dautres Unit.
La clause Uses XXX dans un programme Delphi, permet dindiquer la rfrence la Unit
XXX et autorise laccs aux procdures et fonctions publiques de linterface dans tout le
programme.
Syntaxe :
Exemple :
Unit Truc ;
interface
Uses Machin, Chose;
const
a=10;
x='a';
Type
amoi=12..36;
var
x, y : integer;
z : amoi;
implementation
end.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
276
2.2 Partie " prive " dune UNIT : " Implementation "
Correspond la partie prive du module reprsent par la UNIT. Cette partie intimement lie
linterface, contient le code interne du module. Elle contient deux sortes dlments : les
dclarations compltes des procdures et des fonctions prives ainsi que les structures de
donnes prives. Elle contient aussi les dclarations compltes des fonctions et procdures
publiques dont les en-ttes sont prsentes dans linterface.
Syntaxe :
Exemple :
Unit Truc ;
interface
Uses Machin, Chose;
const
a=10;
x='a';
Type
amoi = 12..36;
var
x, y : integer;
z : amoi;
procedure P1(x:real;var u:integer);
procedure P2(u,v:char;var x,y,t:amoi);
function F(x:real):boolean;
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
277
implementation
procedure P1(x:real;var u:integer);
begin
< corps de procdure>
end;
procedure P2(u,v:char;var x,y,t:amoi);
begin
< corps de procdure>
end;
function F(x:real):boolean;
begin
< corps de fonction>
end;
end.
2.3 Partie initialisation dune UNIT
Il est possible d'initialiser des variables et d'excuter des instructions au lancement de l'UNIT.
Elles correspondent des instructions classiques Pascal sur des donnes publiques ou prives
de la Unit (initialisation de tableaux, mise zro de divers indicateurs, chargement de fichiers
etc...):
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
278
3.3 : Complexit, tri, recherche
Plan du chapitre:
1. Complexit d'un algorithme
1.1 Notions de complexit temporelle et spatiale
1.2 Mesure de la complexit temporelle d'un algorithme
1.3 Notation de Landau O(n)
2. Trier des tableaux en mmoire centrale
2.1 Tri interne, tri externe
2.2 Des algorithmes classiques de tri interne
- Le Tri bulles
- Le Tri par slection
- Le ri par insertion
- Le Tri rapide QuickSort
- Le Tri par tas HeapSort
3. Rechercher dans un tableau
3.1 Recherche dans un tableau non tri
3.2 Recherche dans un tableau tri
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
279
1. Complexit d'un algorithme et performance
Nous faisons la distinction entre les mthodes (algorithmes) de tri d'un grand nombre
d'lments (plusieurs milliers ou plus), et le tri de quelques lments (quelques dizaines, voir
quelques centaines ). Pour de trs petits nombres d'lments, la mthode importe peu. Il est
intressant de pouvoir comparer diffrents algorithmes de tris afin de savoir quand les utiliser.
Ce que nous nonons dans ce paragraphe s'applique en gnral tous les algorithmes et en
particulier aux algorithmes de tris qui en sont une excellente illustration.
1.1 Notions de complexit temporelle et spatiale
L'efficacit d'un algorithme est directement lie au programme implmenter sur un
ordinateur. Le programme va s'excuter en un temps fini et va mobiliser des ressources
mmoires pendant son excution; ces deux paramtres se dnomment complexit temporelle
et complexit spatiale.
Ds le dbut de l'informatique les deux paramtres "temps d'excution" et "place mmoire"
ont eu une importance peu prs gale pour comparer l'efficacit relative des algorithmes. Il
est clair que depuis que l'on peut, cot trs rduit avoir des mmoires centrales d'environ 1
Giga octets dans une machine personnelle, les soucis de place en mmoire centrale qui
s'taient fait jour lorsque l'on travaillait avec des mmoires centrales de 128 Kilo octets (pour
des gros matriels de recherche des annes 70) sont repousss psychologiquement plus loin
pour un utilisateur normal. Comme c'est le systme d'exploitation qui gre la mmoire
disponible ( RAM, cache, virtuelle etc...), les analyses de performances de gestion de la
mmoire peuvent varier pour le mme programme.
Le facteur temps d'excution reste l'lment qualitatif le plus perceptible par l'utilisateur d'un
programme ne serait ce que parce qu'il attend derrire son cran le rsultat d'un travail qui
reprsente l'excution d'un algorithme.
L'informatique reste une science de l'ingnieur ce qui signifie ici, que malgr toutes les tudes
ou les critres thoriques permettant de comparer l'efficacit de deux algorithmes dans
l'absolu, dans la pratique nous ne pourrons pas dire qu'il y a un meilleur algorithme pour
rsoudre tel type de problme. Une mthode pouvant tre lente pour certaines configurations
de donnes et dans une autre application qui travaille systmatiquement sur une configuration
de donnes favorables la mthode peut s'avrer tre la "meilleure".
La recherche de la performance tout prix est aussi inefficace que l'attitude contraire.
Prenons notre compte les recommandations de R.Sedgewick :
Quel que soit le problme mettez d'abord en uvre l'algorithme le plus simple, solution du problme, car le
temps ncessaire l'implantation et la mise au point d'un algorithme "optimis" peut tre bien plus
important que le temps requis pour simplement faire fonctionner un programme lgrement moins rapide.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
280
Il nous faut donc un outil permettant de comparer l'efficacit ou complexit d'un algorithme
celle d'un autre algorithme rsolvant le mme problme.
1.2 Mesure de la complexit temporelle d'un algorithme
- 1.2.1 La complexit temporelle
- 1.2.2 Complexit d'une squence d'instructions
- 1.2.3 Complexit d'une instruction conditionnelle
- 1.2.4 Complexit d'une itration finie borne
Nous prenons le parti de nous intresser uniquement au temps thorique d'excution d'un
algorithme. Pourquoi thorique et non pratique ? Parce que le temps pratique d'excution d'un
programme, comme nous l'avons signal plus haut dpend :
- de la machine (par exemple processeur travaillant avec des jeux d'instructions
optimises ou non),
- du systme d'exploitation (par exemple dans la gestion multi-tche des
processus),
- du compilateur du langage dans lequel l'algorithme sera traduit (compilateur
natif pour un processeur donn ou non),
- des donnes utilises par le programme (nature et/ou taille),
- d'un facteur intrinsque l'algorithme.
Nous souhaitons donc pouvoir utiliser un instrument mathmatique de mesure qui rende
compte de l'efficacit spcifique d'un algorithme indpendamment de son implantation en
langage volu sur une machine. Tout en sachant bien que certains algorithmes ne pourront
pas tre analyss ainsi soit parce que mathmatiquement cela est impossible, soit parce que les
configurations de donnes ne sont pas spcifies d'un manire prcise, soit parce que le temps
mis analyser correctement l'algorithme dpasserait le temps de loisir et de travail disponible
du dveloppeur !
Notre instrument, la complexit temporelle, est fond sur des outils abstraits (qui ont leur
correspondance concrte dans un langage de programmation). L'outil le plus connu est
l'opration lmentaire (quantit abstraite dfinie intuitivement ou d'une manire vidente par
le dveloppeur).
Notion d'opration lmentaire
Une opration lmentaire est une opration fondamentale d'un algorithme si le temps
d'excution est directement li (par une formule mathmatique ou empirique) au nombre de
ces oprations lmentaires. Il peut y avoir plusieurs oprations lmentaires dans un mme
algorithme.
Nous pourrons ainsi comparer deux algorithmes rsolvant le mme problme en comparant ce
nombre d'oprations lmentaires effectues par chacun des deux algorithmes.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
281
1.2.1 La complexit temporelle : notation
C'est le dcompte du nombre d'oprations lmentaires effectues par un algorithme donn.
Il n'existe pas de mthodologie systmatique (art de l'ingnieur) permettant pour un
algorithme quelconque de compter les oprations lmentaires. Toutefois des rgles usuelles
sont communment admises par la communaut des informaticiens qui les utilisent pour
valuer la complexit temporelle.
Soient i
1
, i
2
, ... , i
k
des instructions algorithmiques (affectation, itration, condition,...)
Soit une opration lmentaire dnote OpElem, supposons qu'elle apparaisse n
1
fois dans
l'instruction i
1
, n
2
fois dans l'instruction i
2
, ... n
k
fois dans l'instruction i
k
. Nous noterons
Nb(i
1
) le nombre n
1
, Nb(i
2
) le nombre n
2
etc.
Nous dfinissons ainsi la fonction Nb (i
k
) indiquant le nombre d'oprations lmentaires
dnot OpElemcontenu dans l'instruction algorithmique i
k
:
Nb( ) : Instruction Entier .
1.2.2 Complexit temporelle d'une squence d'instructions
Soit S la squence d'excution des instructions i
1
; i
2
; ... ; i
k
, soit n
k
=Nb (i
k
) le nombre
d'oprations lmentaires de l'instruction i
k
.
Le nombre d'oprations lmentaires OpElemde S, Nb(S) est gal par dfinition la somme
des nombres: n
1
+ n
2
+ ... + n
k
:
S =
dbut
i
1
;
i
2
;
... ;
i
k
fin
Nb( S ) = Nb(i
p
) = n
1
+ n
2
+ ... + n
k
1.2.3 Complexit temporelle d'une instruction conditionnelle
Dans les instructions conditionnelles tant donn qu'il n'est pas possible d'une manire
gnrale de dterminer systmatiquement quelle partie de l'instruction est excute (le alors
ou le sinon), on prend donc un majorant :
Cond =
si Expr alors E1
sinon E2
fsi
Nb( Cond ) < Nb( Expr) + max ( Nb( E1 ) , Nb( E2 ) )
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
282
1.2.4 Complexit temporelle d'une itration finie borne
Dans le cas d'une boucle finie borne (comme pour...fpour) contrle par une variable d'indice
"i", l'on connat le nombre exact d'itrations not Nbr_d'itrations de l'ensemble des
instructions composant le corps de la boucle dnotes S (o S est une squence
d'instructions), l'arrt tant assur par la condition de sortie Expr(i) dpendant de la variable
d'indice de boucle i.
La complexit est gale au produit du nombre d'itrations par la somme de la complexit de la
squence d'instructions du corps et de celle de l'valuation de la condition d'arrt Expr(i).
Iter =
Itration Expr(i)
S
finItr
Nb( Iter ) = [ Nb( S) + Nb(Expr(i)) ] x Nbr_d'itrations
Exemple dans le cas d'une boucle pour...fpour :
Iter =
pour i<-- a jusqu b faire
i
1
;
i
2
;
... ;
i
k
fpour
La complexit de la condition d'arrt est par dfinition de 1 (<= le temps d'excution de
l'opration effectue en l'occurence un test, ne dpend ni de la taille des donnes ni de leurs
valeurs), en notant |b-a| le nombre exact d'itrations excutes (lorsque les bornes sont des
entiers |b-a| vaut exactement la valeur absolue de la diffrence des bornes) nous avons :
Nb( Iter ) = ( Nb(i
p
) + 1 ) . |b-a|
Lorsque le nombre d'itrations n'est pas connu mais seulement major ( nombre not
Majorant_Nbr_d'itrations ), alors on obtient un majorant de la complexit de la boucle (le
majorant correspond la complexit dans le pire des cas).
Complexit temporelle au pire :
Majorant_Nb( Iter ) = [ Nb( S) + Nb(Expr(i)) ] x Majorant_Nbr_d'itrations
1.3 Notation de Landau O(n)
Nous avons admis l'hypothse qu'en rgle gnrale la complexit en temps dpend de la
taille n des donnes (plus le nombre de donnes est grand plus le temps d'excution est long).
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
283
Cette remarque est d'autant plus proche de la ralit que nous tudierons essentiellement des
algorithmes de tri dans lesquels les n donnes sont reprsentes par une liste n lments.
Afin que notre instrument de mesure et de comparaison d'algorithmes ne dpende pas de la
machine physique, nous n'exprimons pas le temps d'excution en units de temps
(millisecondes etc..) mais en unit de taille des donnes.
Nous ne souhaitons pas ici rentrer dans le dtail mathmatique des notations O(f(n)) de
Landau sur les infiniment grands quivalents, nous donnons seulement une utilisation pratique
de cette notation.
Pour une fonction f (n) dpendant de la variable n, on crit :
f est O(g(n)) g(n) o g est elle-mme une fonction de la variable entire n, et l'on lit f est de
l'ordre de grandeur de g(n) ou plus succinctement f est d'ordre g(n), lorsque :
f est d'ordre g(n) :
Pour tout valeur entire de n, il existe deux constantes a et b positives
telles que : a.g(n) < f(n) < b.g(n)
Ce qui signifie que lorsque n tend vers l'infini (n devient trs grand en informatique) le
rapport f(n)/g(n) reste born.
f est d'ordre g(n) :
a < f(n)/g(n) < b quand n
Lorsque n tend vers l'infini, le rapport f(n)/g(n) reste born.
Exemple :
Supposons que f et g soient les polynmes suivants :
f(n) = 3n
2
- 7n +4
g(n) = n
2
;
Lorsque n tend vers l'infini le rapport f(n)/g(n) tend vers 3:
f(n)/g(n) 3 quand n
ce rapport est donc born.
donc f est d'ordre n
2
ou encore f est O(n
2
)
C'est cette notation que nous utiliserons pour mesurer la complexit temporelle C en nombre
d'oprations lmentaires d'un algorithme fix. Il suffit pour pouvoir comparer des
complexits temporelles diffrentes, d'utiliser les mmes fonctions g(n) de base.
Les informaticiens ont rpertori des situations courantes et ont calcul l'ordre de complexit
associ ce genre de situation.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
284
Les fonctions g(n) classiquement et pratiquement les plus utilises sont les suivantes :
g(n) = 1
g(n) = log
k
(n)
g(n) = n
g(n) = n.log
k
(n)
g(n) = n
2
Ordre de complexit C Cas d'utilisation courant
g(n) = 1 C est O(1) Algorithme ne dpendant pas des donnes
g(n) = log
k
(n) C est O(log
k
(n))
Algorithme divisant le problme par une quantit
constante (base k du logarithme)
g(n) = n C est O(n)
Algorithme travaillant directement sur chacune des
n donnes
g(n) = n.log
k
(n) C est O(n.log
k
(n))
Algorithme divisant le problme en nombre de
sous-problmes constants (base k du logarithme),
dont les rsultats sont rutiliss par recombinaison
g(n) = n
2
C est O(n
2
)
Algorithme traitant gnralement des couples de
donnes (dans deux boucles imbriques).
2. Trier des tableaux en mmoire centrale
Un tri est une opration de classement d'lments d'une liste selon un ordre total dfini. Sur
le plan pratique, on considre gnralement deux domaines d'application des tris: les tris
internes et les tris externes.
Que se passe-t-il dans un tri? On suppose qu'on se donne une suite de nombres entiers (ex: 5,
8, -3 ,6 ,42, 2,101, -8, 42, 6) et l'on souhaite les classer par ordre croissant (relation d'ordre au
sens large). La suite prcdente devient alors aprs le tri (classement) : (-8, -3, 2, 5, 6, 6, 8, 42,
42, 101). Il s'agit en fait d'une nouvelle suite obtenue par une permutation des lments de la
premire liste de telle faon que les lments rsultants soient classs par ordre croissant au
sens large selon la relation d'ordre totale " s " : (-8 s -3 s 2 s 5 s 6 s 6 s 8 s 42 s 42 s
101).
Cette opration se retrouve trs souvent en informatique dans beaucoup de structures de
donnes. Par exemple, il faut tablir le classement de certains lves, mettre en ordre un
dictionnaire, trier l'index d'un livre, etc...
2.1 Tri interne, tri externe
Un tri interne s'effectue sur des donnes stockes dans une table en mmoire centrale, un tri
externe est relatif une structure de donnes non contenue entirement dans la mmoire
centrale (comme un fichier sur disque par exemple).
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
285
Dans certains cas les donnes peuvent tre stockes sur disque (mmoire secondaire) mais
structures de telle faon que chacune d'entre elles soit reprsente en mmoire centrale par
une clef associe un pointeur. Le pointeur li la clef permet alors d'atteindre l'lment sur
le disque (n d'enregistrement...). Dans ce cas seules les clefs sont tries (en table ou en arbre)
en mmoire centrale et il s'agit l d'un tri interne. Nous rservons le vocable tri externe
uniquement aux manipulations de tris directement sur les donnes stockes en mmoire
secondaire.
2.2 Des algorithmes classiques de tri interne
Dans les algorithmes rfrencs ci-dessous, nous notons (a
1
, a
2
, ... , a
n
) la liste trier. Etant
donn le mode d'accs en mmoire centrale (accs direct aux donnes) une telle liste est
gnralement implante selon un tableau une dimension de n lments (cas le plus courant).
Nous attachons dans les algorithmes prsents, expliciter des tris majoritairement sur des
tables, certains algorithmes utiliserons des structures d'arbres en mmoire centrale pour
reprsenter notre liste trier (a
1
, a
2
, ... , a
n
).
Les oprations lmentaires principales les plus courantes permettant les calculs de
complexit sur les tris, sont les suivantes :
Deux oprations lmentaires
La comparaison de deux lments de la liste a
i
et a
k
, (si a
i
> a
k
, si ai < ak,....) .
L'change des places de deux lments de la liste a
i
et a
k
, (place (a
i
) place (a
k
) ).
Ces deux oprations seront utilises afin de fournir une mesure de comparaison des tris entre
eux. Nous proposons dans les pages suivantes cinq tris classiques, quatre concerne le tri de
donnes dans un tableau, le cinquime est un tri de donnes situes dans un arbre binaire, ce
dernier pourra en premire lecture tre ignor, si le lecteur n'est pas familiaris avec la notion
d'arbre binaire
Tris sur des tables :
- Tri itratif bulles
- Tri itratif par slection
- Tri itratif par insertion
- Tri rcursif rapide QuickSort
Tris sur un arbre binaire :
- Le Tri par tas / HeapSort
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
286
Le tri bulle
- A) Spcification abstraite
- B) Spcification concrte
- C) Algorithme
- D) Complexit
- E) Programme Delphi - Java
- F) Assistant visuel
C'est le moins performant de la catgorie des tris par change ou slection, mais comme c'est
un algorithme simple, il est intressant utiliser pdagogiquement.
A) Spcification abstraite
Nous supposons que les donnes a
1
, a
2
, ... , a
n
sont mises sous forme d'une liste (a
1
, a
2
, ... ,
a
n
), le principe du tri bulle est de parcourir la liste (a
1
, a
2
, ... , a
n
) en intervertissant toute
paire d'lments conscutifs (a
i-1
, a
i
) non ordonns.
Ainsi aprs le premier parcours, l'lment maximum se retrouve en a
n
. On suppose que
l'ordre s'crit de gauche droite ( gauche le plus petit lment, droite le plus grand
lment).
On recommence l'opration avec la nouvelle sous-suite (a
1
, a
2
, ... , a
n-1
), et ainsi de suite
jusqu' puisement de toutes les sous-suites (la dernire est un couple).
Le nom de tri bulle vient donc de ce qu' la fin de chaque itration interne, les plus grands
nombres de chaque sous-suite se dplacent vers la droite successivement comme des bulles de
la gauche vers la droite.
B) Spcification concrte
La suite (a
1
, a
2
, ... , a
n
) est range dans un tableau une dimension T[...] en mmoire centrale.
Le tableau contient une partie trie (en fonc droite) et une partie non trie (en blanc
gauche).
On effectue plusieurs fois le parcours du tableau trier.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
287
Le principe de base est de r-ordonner les couples (a
i-1
, a
i
) non classs (en inversion de rang
soit a
i-1
> a
i
) dans la partie non trie du tableau, puis dplacer la frontire (le maximum de la
sous-suite (a
1
, a
2
, ... , a
n-1
) ) d'une position :
Tant que la partie non trie n'est pas vide, on permute les couples non ordonns ( (a
i-1
, a
i
) tels
que a
i-1
> a
i
) ) pour obtenir le maximum de celle-ci llment frontire. C'est dire qu'au
premier passage c'est l'extremum global qui est bien class, au second passage le second
extremum etc...
C) Algorithme :
Algorithme Tri_a_Bulles
local: i , j , n, temp e Entiers naturels
Entre : Tab e Tableau d'Entiers naturels de 1 n lments
Sortie : Tab e Tableau d'Entiers naturels de 1 n lments
dbut
pour i de n jusqu 1 faire // recommence une sous-suite (a
1
, a
2
, ... , a
i
)
pour j de 2 jusqu i faire // change des couples non classs de la sous-suite
si Tab[ j-1 ] > Tab[ j ] alors // a
j-1
et a
j
non ordonns
temp Tab[ j-1 ] ;
Tab[ j-1 ] Tab[ j ] ;
Tab[ j ] temp //on change les positions de a
j-1
et a
j
Fsi
fpour
fpour
Fin Tri_a_Bulles
Exemple : soit la liste ( 5 , 4 , 2 , 3 , 7 , 1 ), appliquons le tri bulles sur cette liste d'entiers.
Visualisons les diffrents tats de la liste pour chaque itration externe contle par l'indice i :
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
288
i = 6 / pour j de 2 jusqu 6 faire
i = 5 / pour j de 2 jusqu 5 faire
i = 4 / pour j de 2 jusqu 4 faire
i = 3 / pour j de 2 jusqu 3 faire
i = 2 / pour j de 2 jusqu 2 faire
i = 1 / pour j de 2 jusqu 1 faire (boucle vide)
D) Complexit :
Choisissons comme opration lmentaire la comparaison de deux cellules du tableau.
Le nombre de comparaisons "si Tab[ j-1 ] > Tab[ j ] alors" est une valeur qui ne dpend que
de la longueur n de la liste (n est le nombre d'lments du tableau), ce nombre est gal au
nombre de fois que les itrations s'excutent, le comptage montre que la boucle "pour i de n
jusqu 1 faire" s'excute n fois (donc une somme de n termes) et qu' chaque fois la boucle
"pour j de 2 jusqu i faire" excute (i-2)+1 fois la comparaison "si Tab[ j-1 ] > Tab[ j ]
alors".
Choix opration
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
289
La complexit en nombre de comparaison est gale la somme des n termes suivants (i = n, i
= n-1,.... i = 1)
C = (n-2)+1 + ([n-1]-2)+1 +.....+1+0 = (n-1)+(n-2)+...+1 = n(n-1)/2 (c'est la somme des n-1
premiers entiers).
La complexit du tri bulle en nombre de comparaison est de de l'ordre de n
2
, que l'on
crit O(n
2
).
Choisissons comme opration lmentaire l'change de deux cellules du tableau.
Calculons par dnombrement le nombre d'changes dans le pire des cas (complexit au pire =
majorant du nombre d'changes). Le cas le plus mauvais est celui o le tableau est dj class
mais dans l'ordre inverse et donc chaque cellule doit tre change, dans cette ventualit il y
a donc autant d'changes que de tests.
La complexit du tri bulle au pire en nombre d'changes est de l'ordre de n
2
, que l'on
crit O(n
2
).
E) Programme Delphi (tableau d'entiers):
program TriParBulle;
const N = 10; { Limite suprieure de tableau }
type TTab = array [1..N] of integer; { TTab : Type Tableau }
var Tab : TTab ;
procedure TriBulle (var Tab:TTab) ;
{ Implantation Pascal de l'algorithme }
var i, j, t : integer;
begin
for i := N downto 1 do
for j := 2 to i do
if Tab[j-1] > Tab[j] then
begin
t := Tab[j-1];
Tab[j-1] := Tab[j];
Tab[j] := t;
end;
end;
procedure Initialisation(var Tab:TTab) ;
{ Tirage alatoire de N nombres de 1 100 }
Choix opration
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
290
var i : integer; { i : Indice de tableau de N colonnes }
begin
randomize;
for i := 1 to N do
Tab[i] := random(100);
end;
procedure Impression(Tab:TTab) ;
{ Affichage des N nombres dans les colonnes }
var i : integer;
begin
writeln('------------------------');
for i:= 1 to N do write(Tab[i] : 3, ' | ');
writeln;
end;
begin
Initialisation(Tab);
writeln('TRI PAR BULLE');
writeln;
Impression(Tab);
TriBulle(Tab);
Impression(Tab);
writeln('----------------------');
end.
Rsultat de l'excution du programme prcdent :
E) Programme Java (tableau d'entiers) :
class ApplicationTriBulle {
static int[] table = new int[10] ; // le tableau trier en attribut
static void TriBulle ( ) {
int n = table.length-1;
for ( int i = n; i>=1; i--)
for ( int j = 2; j<=i; j++)
if (table[j-1] > table[j])
{
int temp = table[j-1];
table[j-1] = table[j];
table[j] = temp;
}
}
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
291
static void Impression ( ) {
// Affichage du tableau
int n = table.length-1;
for ( int i = 1; i<=n; i++)
System.out.print(table[i]+" , ");
System.out.println();
}
static void Initialisation ( ) {
// remplissage alatoire du tableau
int n = table.length-1;
for ( int i = 1; i<=n; i++)
table[i] = (int)(Math.random()*100);
}
public static void main(String[ ] args) {
Initialisation ( );
System.out.println("Tableau initial :");
Impression ( );
TriBulle ( );
System.out.println("Tableau une fois tri :");
Impression ( );
}
}
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
292
Le tri par slection
- A) Spcification abstraite
- B) Spcification concrte
- C) Algorithme
- D) Complexit
- E) Programme Delphi - Java
C'est une version de base de la catgorie des tris par slection.
A) Spcification abstraite
Nous supposons que les donnes a
1
, a
2
, ... , a
n
sont mises sous forme d'une liste (a
1
, a
2
, ... ,
a
n
), la liste (a
1
, a
2
, ... , a
n
) est dcompose en deux parties : une partie liste (a
1
, a
2
, ... , a
k
) et
une partie non-trie (a
k+1
, a
k+2
, ... , a
n
); l'lment a
k+1
est appel lment frontire (c'est le
premier lment non tri).
Le principe est de parcourir la partie non-trie de la liste (ak+1, ak+2, ... , an) en cherchant
l'lment minimum, puis en l'changeant avec l'lment frontire ak+1, puis dplacer la
frontire d'une position. Il s'agit d'une rcurrence sur les minima successifs. On suppose que
l'ordre s'crit de gauche droite ( gauche le plus petit lment, droite le plus grand
lment).
On recommence l'opration avec la nouvelle sous-suite (ak+2, ... , an) , et ainsi de suite
jusqu' ce que la dernire soit vide.
B) Spcification concrte
La suite (a
1
, a
2
, ... , a
n
) est range dans un tableau une dimensionT[...] en mmoire centrale.
Le tableau contient une partie trie (en fonc gauche) et une partie non trie (en blanc
droite).
On cherche le minimum de la partie non-trie du tableau et on le recopie dans la cellule
frontire (le premier lment de la partie non trie).
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
293
Donc pour tout a
p
de la partie non trie on effectue l'action suivante :
si a
k+1
> a
p
alors a
k+1
a
p
Fsi
et l'on obtient ainsi la fin de l'examen de la sous-liste (a
k+1
,
ak+2
, ... , a
n
) la valeur min (a
k+1
,
a
k+2
, ... , a
n
) stocke dans la cellule a
k+1
.
La sous-suite (a
1
, a
2
, ... , a
k
, a
k+1
) est maintenant trie :
Et l'on recommence la boucle de recherche du minimum sur la nouvelle sous-liste (a
k+2
, a
k+3
,
... , a
n
) etc...
Tant que la partie non trie n'est pas vide, on range le minimum de la partie non-trie dans
llment frontire.
C) Algorithme :
Une version maladroite de l'algorithme mais exacte a t fournie par un groupe d'tudiants
elle est dnomme / Version maladroite 1/.
Elle change physiquement et systmatiquement l'lment frontire Tab[ i ] avec un lment
Tab[ j ] dont la valeur est plus petite (la suite (a
1
, a
2
, ... , a
i
) est trie) :
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
294
Algorithme Tri_Selection /Version maladroite 1/
local: m, i , j , n, temp e Entiers naturels
Entre : Tab e Tableau d'Entiers naturels de 1 n lments
Sortie : Tab e Tableau d'Entiers naturels de 1 n lments
dbut
pour i de 1 jusqu n-1faire // recommence une sous-suite
m i ; // i est l'indice de l'lment frontire Tab[ i ]
pour j de i+1 jusqu n faire// liste non-trie : (a
i+1
, a
i+2
, ... , a
n
)
si Tab[ j ] < Tab[ m ] alors // a
j
est le nouveau minimum partiel
m j ;
temp Tab[ m ] ;
Tab[ m ] Tab[ i ] ;
Tab[ i ] temp //on change les positions de a
i
et de a
j
m i ;
Fsi
fpour
fpour
Fin Tri_Selection
Voici une version correcte et amliore du prcdent (nous allons voir avec la notion de complexit
comment appuyer cette intuition d'amlioration), dans laquelle l'on sort l'change a
i
et a
j
de la boucle
interne "pour j de i+1 jusqu n faire" pour le dporter la fin de cette boucle.
Au lieu de travailler sur les contenus des cellules de la table, nous travaillons sur les
indices, ainsi lorsque aj est plus petit que ai nous mmorisons l'indice "j" du minimum dans
une variable " m j ; " plutt que le minimum lui-mme.
Version maladroite Version amliore
pour j de i+1 jusqu n faire
si Tab[ j ] < Tab[ m ] alors
m j ;
temp Tab[ m ] ;
Tab[ m ] Tab[ i ] ;
Tab[ i ] temp
m i ;
Fsi
fpour
pour j de i+1 jusqu n faire
si Tab[ j ] < Tab[ m ] alors
m j ;
Fsi
fpour;
temp Tab[ m ] ;
Tab[ m ] Tab[ i ] ;
Tab[ i ] temp
Maladroit
Amlioration
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
295
A la fin de la boucle interne "pour j de i+1 jusqu n faire" la variable m contient l'indice de
min(ai+1, ak+2, ... , an) et l'on permute l'lment concern (d'indice m) avec l'lment
frontire ai :
Algorithme Tri_Selection /Version 2 amliore/
local: m, i , j , n, temp e Entiers naturels
Entre : Tab e Tableau d'Entiers naturels de 1 n lments
Sortie : Tab e Tableau d'Entiers naturels de 1 n lments
dbut
pour i de 1 jusqu n-1 faire // recommence une sous-suite
m i ; // i est l'indice de l'lment frontire ai = Tab[ i ]
pour j de i+1 jusqu n faire// (a
i+1
, a
i+2
, ... , a
n
)
si Tab[ j ] < Tab[ m ] alors // aj est le nouveau minimum partiel
m j ; // indice mmoris
Fsi
fpour;
temp Tab[ m ] ;
Tab[ m ] Tab[ i ] ;
Tab[ i ] temp //on change les positions de a
i
et de a
j
fpour
Fin Tri_Selection
D) Complexit :
Choisissons comme opration lmentaire la comparaison de deux cellules du tableau.
Pour les deux versions 1 et 2 :
Le nombre de comparaisons "si Tab[ j ] < Tab[ m ] alors" est une valeur qui ne dpend que
de la longueur n de la liste (n est le nombre d'lments du tableau), ce nombre est gal au
nombre de fois que les itrations s'excutent, le comptage montre que la boucle "pour i de 1
jusqu n-1 faire" s'excute n-1 fois (donc une somme de n-1 termes) et qu' chaque fois la
boucle "pour j de i+1 jusqu n faire" excute (n-(i+1)+1 fois la comparaison "si Tab[ j ] <
Tab[ m ] alors".
La complexit en nombre de comparaison est gale la somme des n-1 termes suivants (i = 1,
...i = n-1)
C = (n-2)+1 + (n-3)+1 +.....+1+0 = (n-1)+(n-2)+...+1 = n.(n-1)/2 (c'est la somme des n-1
premiers entiers).
La complexit du tri par slection en nombre de comparaison est de de l'ordre de n
2
,
que l'on crit O(n
2
).
Choix opration
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
296
Choisissons comme opration lmentaire l'change de deux cellules du tableau.
Calculons par dnombrement le nombre d'changes dans le pire des cas (complexit au pire =
majorant du nombre d'changes). Le cas le plus mauvais est celui o le tableau est dj class
mais dans l'ordre inverse.
Pour la version 1
Au pire chaque cellule doit tre change, dans cette ventualit il y a donc
autant d'changes que de tests.
La complexit au pire en nombre d'changes de la version 1 est de
l'ordre de n
2
, que l'on crit O(n
2
).
Pour la version 2
L'change a lieu systmatiquement dans la boucle principale "pour i de 1
jusqu n-1 faire" qui s'excute n-1 fois :
La complexit en nombre d'changes de cellules de la version 2 est
de l'ordre de n, que l'on crit O(n).
Un change valant 3 transferts (affectation) la complexit en
transfert est O(3n) = O(n)
Toutefois cette complexit en nombre d'changes de cellules n'apparat pas comme
significative du tri, outre le nombre de comparaison, c'est le nombre d'affectations d'indice qui
reprsente une opration fondamentale et l les deux versions ont exactement la mme
complexit O(n
2
).
Exemple : soit la liste 6 lments ( 5 , 4 , 2 , 3 , 7 ,1 ), appliquons la version 2 du tri par
slection sur cette liste d'entiers. Visualisons les diffrents tats de la liste pour la premire
itration externe contrle par i (i = 1) et pour les itrations internes contrles par l'indice j
(de j = 2 ... ... j = 6) :
comme 5>4 on mmorise dans m
comme 4>2 on mmorise dans m comme 2<3 on ne mmorise pas
comme 2<7 on ne mmorise pas comme 2>1 on mmorise dans m
on change T[1] et T[6]
Choix opration
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
297
L'algorithme ayant termin l'change de T[1] et de T[6], il passe l'itration externe suivante
(dans pour i de 1 jusqu n-1 faire , il passe i = 2) :
etc....
E) Programme Delphi (tableau d'entiers) :
program TriParSelection;
const N = 10; { Limite suprieure de tableau }
type TTab = array [1..N] of integer; { TTab : Type Tableau }
var Tab : TTab ;
procedure TriSelection (var Tab:TTab) ;
{ Implantation Pascal de l'algorithme }
var i, j, t, m : integer;
begin
for i := 1 to N-1 do
begin
m := i;
for j := i+1 to N do
if Tab[ j ] < Tab[ m ] then m := j;
t := Tab[m];
Tab[m] := Tab[i];
Tab[i] := t;
end;
end;
procedure Initialisation(var Tab:TTab) ;
{ Tirage alatoire de N nombres de 1 100 }
var i : integer; { i : Indice de tableau de N colonnes }
begin
randomize;
for i := 1 to N do
Tab[i] := random(100);
end;
procedure Impression(Tab:TTab) ;
{ Affichage des N nombres dans les colonnes }
var i : integer;
begin
writeln('------------------------');
for i:= 1 to N do write(Tab[i] : 3, ' | ');
writeln;
end;
begin
Initialisation(Tab);
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
298
writeln('TRI PAR SELECTION');
writeln;
Impression(Tab);
TriSelection(Tab);
Impression(Tab);
writeln('----------------------');
end.
Rsultat de l'excution du programme prcdent :
E) Programme Java (tableau d'entiers) :
class ApplicationTriSelect
{
static int[] table = new int[20] ; // le tableau trier en attribut
static void Impression ( ) {
// Affichage du tableau
int n = table.length-1;
for ( int i = 1; i<=n; i++)
System.out.print(table[i]+" , ");
System.out.println();
}
static void Initialisation ( ) {
// remplissage alatoire du tableau
int n = table.length-1;
for ( int i = 1; i<=n; i++)
table[i] = (int)(Math.random()*100);
}
static void TriSelect ( ) {
int n = table.length-1;
for ( int i = 1; i <= n-1; i++)
{ // recommence une sous-suite
int m = i; // lment frontire ai = table[ i ]
for ( int j = i+1; j <= n; j++) // (ai+1, a2, ... , an)
if (table[ j ] < table[ m ]) // aj = nouveau minimum partiel
m = j ; // indice mmoris
int temp = table[ m ];
table[ m ] = table[ i ];
table[ i ]= temp;
}
}
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
299
public static void main(String[ ] args)
{
Initialisation ( );
System.out.println("Tableau initial :");
Impression ( );
TriSelect ( );
System.out.println("Tableau une fois tri :");
Impression ( );
}
}
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
300
Le tri par insertion
- A) Spcification abstraite
- B) Spcification concrte
- C) Algorithme
- D) Complexit
- E) Programme Delphi - Java
C'est un tri en gnral un peu plus coteux en particulier en nombre de transfert
effectuer qu'un tri par slection (cf. complexit).
A) Spcification abstraite
Nous supposons que les donnes a
1
, a
2
, ... , a
n
sont mises sous forme d'une liste (a
1
, a
2
, ... ,
a
n
), le principe du tri par insertion est de parcourir la liste non trie liste (a
1
, a
2
, ... , a
n
) en la
dcomposant en deux parties : une partie dj trie et une partie non trie.
La mthode est identique celle que l'on utilise pour ranger des cartes que l'on tient dans sa
main : on insre dans le paquet de cartes dj ranges une nouvelle carte au bon endroit.
L'opration de base consiste prendre l'lment frontire dans la partie non trie, puis
l'insrer sa place dans la partie trie (place que l'on recherchera squentiellement), puis
dplacer la frontire d'une position vers la droite. Ces insertions s'effectuent tant qu'il reste un
lment ranger dans la partie non trie.. L'insertion de l'lment frontire est effectue par
dcalages successifs d'une cellule.
La liste (a
1
, a
2
, ... , a
n
) est dcompose en deux parties : une partie trie (a
1
, a
2
, ... , a
k
) et une
partie non-trie (a
k+1
, a
k+2
, ... , a
n
); l'lment a
k+1
est appel lment frontire (c'est le premier
lment non tri).
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
301
B) Spcification concrte itrative
La suite (a
1
, a
2
, ... , a
n
) est range dans un tableau une dimension T[...] en mmoire centrale.
Le tableau contient une partie trie ( (a
1
, a
2
, ... , a
k
) en fonc gauche) et une partie non trie (
(a
k+1
, a
k+2
, ... , a
n
); en blanc droite) :
On insre l'lment frontire a
k+1
en faisant varier j de k jusqu' 2 , afin de balayer toute la
partie (a1, a2, ... , ak) dj range, on dcale alors d'une place les lments plus grands que
l'lment frontire :
tantque a
j-1
> a
k+1
faire
dcaler a
j-1
en a
j
;
passer au j prcdent
ftant
La boucle s'arrte lorsque a
j-1
< a
k+1
,ce qui veut dire que l'on vient de trouver au rang j-1 un
lment a
j-1
plus petit que l'lment frontire a
k+1
, donc a
k+1
doit tre plac au rang j.
C) Algorithme :
Algorithme Tri_Insertion
local: i , j , n, v e Entiers naturels
Entre : Tab e Tableau d'Entiers naturels de 0 n lments
Sortie : Tab e Tableau d'Entiers naturels de 0 n lments
{ dans la cellule de rang 0 se trouve une sentinelle charge d'viter de tester dans la
boucle tantque .. faire si l'indice j n'est pas infrieur 1, elle aura une valeur
infrieure toute valeur possible de la liste
}
dbut
pour i de2 jusqu n faire// la partie non encore trie (a
i
, a
i+1
, ... , a
n
)
v Tab[ i ] ; // l'lment frontire : a
i
j i ; // le rang de l'lment frontire
Tantque Tab[ j-1 ] > v faire // on travaille sur la partie dj trie (a
1
, a
2
, ... , a
i
)
Tab[ j ] Tab[ j-1 ]; // on dcale l'lment
j j-1; // on passe au rang prcdent
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
302
FinTant ;
Tab[ j ] v //on recopie a
i
dans la place libre
fpour
Fin Tri_Insertion
Sans la sentinelle en T[0] nous aurions une comparaison sur j l'intrieur de la boucle :
Tantque Tab[ j-1 ] > v faire//on travaille sur la partie dj trie(a
1
, a
2
, ... , a
i
)
Tab[ j ] Tab[ j-1 ]; // on dcale l'lment
j j-1; // on passe au rang prcdent
si j = 0 alors Sortir de la boucle fsi
FinTant ;
Exercice
Un tudiant a propos d'intgrer la comparaison dans le test de la boucle en
crivant ceci :
Tantque ( Tab[j-1] > v ) et ( j >0 ) faire
Tab[ j ] Tab[ j-1 ];
j j-1;
FinTant ;
Il a eu des problmes de dpassement d'indice de tableau lors de
l'implmentation de son programme.
Essayez d'analyser l'origine du problme en notant que la prsence d'une
sentinelle limine le problme.
D) Complexit :
Choisissons comme opration lmentaire la comparaison de deux cellules du tableau.
Dans le pire des cas le nombre de comparaisons "Tantque Tab[ j-1 ] > v faire" est une valeur
qui ne dpend que de la longueur i de la partie (a1, a2, ... , ai) dj range. Il y a donc au pire i
comparaisons pour chaque i variant de 2 n :
La complexit au pire en nombre de comparaison est donc gale la somme des n termes
suivants (i = 2, i = 3,.... i = n)
C = 2 + 3 + 4 +...+ n = n(n+1)/2 -1 comparaisons au maximum. (c'est la somme des n
premiers entiers moins 1).
La complexit au pire en nombre de comparaison est de l'ordre de n
2
, que l'on crit
O(n
2
).
Choix opration
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
303
Choisissons maintenant comme opration lmentaire le transfert d'une cellule du tableau.
Calculons par dnombrement du nombre de transferts dans le pire des cas .
Il y a autant de transferts dans la boucle "Tantque Tab[ j-1 ] > v faire" qu'il y a de
comparaisons il faut ajouter 2 transferts par boucle "pour i de 2 jusqu n faire", soit au total
dans le pire des cas :
C = n(n+1)/2 + 2(n-1) = (n + 5n - 4)/2
La complexit du tri par insertion au pire en nombre de transferts est de l'ordre de n
2
,
que l'on crit O(n
2
).
E) Programme Delphi (tableau d'entiers) :
program TriParInsertion;
const N = 10; { Limite suprieure de tableau }
type TTab = array [0..N]of integer; { TTab : Type Tableau }
var Tab : TTab ;
procedure TriInsertion (var Tab:TTab) ;
{ Implantation Pascal de l'algorithme }
var i, j, v : integer;
begin
for i := 2 to N do
begin
v := Tab[ i ];
j := i ;
while Tab[ j-1 ] > v do
begin
Tab[ j ] := Tab[ j-1 ] ;
j := j - 1 ;
end;
Tab[ j ] := v ;
end
end;
procedure Initialisation(var Tab:TTab) ;
{ Tirage alatoire de N nombres de 1 100 }
var i : integer; { i : Indice de tableau de N colonnes }
begin
randomize;
for i := 1 to N do
Tab[i] := random(100);
Tab[0]:= -Maxint ; // la sentinelle est l'entier le plus petit du type
integer sur la machine
end;
Choix opration
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
304
procedure Impression(Tab:TTab) ;
{ Affichage des N nombres dans les colonnes }
var i : integer;
begin
writeln('------------------------');
for i:= 1 to N do write(Tab[i] : 3, ' | ');
writeln;
end;
begin
Initialisation(Tab);
writeln('TRI PAR INSERTION');
writeln;
Impression(Tab);
TriInsertion(Tab);
Impression(Tab);
writeln('----------------------');
end.
Rsultat de l'excution du programme prcdent :
E) Programme Java (tableau d'entiers) :
class ApplicationTriInsert
{
// le tableau trier:
static int[] table = new int[10] ;
/*---------------------------------------------------------------------
Dans la cellule de rang 0 se trouve une sentinelle charge d'viter de tester dans la boucle tantque .. faire si
l'indice j n'est pas infrieur 1, elle aura une valeur infrieure toute valeur possible de la liste
--------------------------------------------------------------------*/
static void Impression ( ) {
// Affichage du tableau
int n = table.length-1;
for ( int i = 0; i<=n; i++)
System.out.print(table[i]+" , ");
System.out.println();
}
static void Initialisation ( ) {
// remplissage alatoire du tableau
int n = table.length-1;
for ( int i = 1; i<=n; i++)
table[i] = (int)(Math.random()*100);
//sentinelle l'indice 0 :
table[0] = -Integer.MAX_VALUE;
}
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
305
public static void main(String[ ] args) {
Initialisation ( );
System.out.println("Tableau initial :");
Impression ( );
TriInsert ( );
System.out.println("Tableau une fois tri :");
Impression ( );
}
static void TriInsert ( ) {
// sous-programme de Tri par insertion :
int n = table.length-1;
for ( int i = 2; i <= n; i++)
{
int v = table[i];
int j = i;
while (table[ j-1 ] > v)
{// travail sur la partie dj trie (a1, a2, ... , ai)
table[ j ] = table[ j-1 ]; // on dcale l'lment
j--; // on passe au rang prcdent
}
table[ j ] = v ; //on recopie ai dans la place libre
}
}
}
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
306
Le tri rapide
mthode Sedgewick
- A) Spcification abstraite
- B) Spcification concrte
- C) Algorithme
- D) Complexit
- E) Programme Delphi - Java
C'est le plus performant des tris en table qui est certainement celui qui est le plus
employ dans les programmes. Ce tri a t trouv par C.A.Hoare, nous nous rfrons
Robert Sedgewick qui a travaill dans les annes 70 sur ce tri et l'a amlior et nous
renvoyons son ouvrage pour une tude complte de ce tri. Nous donnons les principes
de ce tri et sa complexit en moyenne et au pire.
A) Spcification abstraite
Nous supposons que les donnes a
1
, a
2
, ... , a
n
sont mises sous forme d'une liste (a
1
, a
2
, ... ,
a
n
), le principe du tri par insertion est de parcourir la liste L = liste (a
1
, a
2
, ... , a
n
) en la
divisant systmatiquement en deux sous-listes L1 et L2. L'une de ces deux sous-listes est telle
que tous ses lments sont infrieurs tous ceux de l'autre liste , la division en sous-liste a
lieu en travaillant sparment sur chacune des deux sous-listes en appliquant nouveau la
mme division chaque sous-liste jusqu' obtenir uniquement des sous-listes un seul
lment.
C'est un algorithme dichotomique qui divise donc le problme en deux sous-problmes dont
les rsultats sont rutiliss par recombinaison, il est donc de complexit O(n.log(n)).
Pour partitionner une liste L en deux sous-listes L1 et L2 :
- on choisit une valeur quelconque dans la liste L (la dernire par exemple) que l'on
dnomme pivot,
- puis on construit la sous-liste L1 comme comprenant tous les lments de L dont la
valeur est infrieure ou gale au pivot,
- et l'on construit la sous-liste L2 comme constitue de tous les lments dont la valeur
est suprieure au pivot.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
307
Soit sur un exemple de liste L :
L = [ 4, 23, 3, 42, 2, 14, 45, 18, 38, 16 ]
prenons comme pivot la dernire valeur pivot = 16
Nous obtenons deux sous-listes L1 et L2 :
L1 = [4, 14, 3, 2]
L2 = [23, 45, 18, 38, 42]
A cette tape voici l'arrangement de L :
L = L1 + pivot + L2 = [4, 14, 3, 2, 16, 23, 45, 18, 38, 42]
En effet, en travaillant sur la table elle-mme par rarrangement des valeurs, le pivot 16 est
plac au bon endroit directement :
[4<16, 14<16, 3<16, 2<16, 16, 23>16, 45>16, 18>16, 38>16, 42>16]
En appliquant la mme dmarche au deux sous-listes : L1 (pivot=2) et L2 (pivot=42)
[4, 14, 3, 2, 16, 23, 45, 18, 38, 42] nous obtenons :
L11=[ ] liste vide
L12=[3, 4, 14]
L1=L11 + pivot + L12 = (2,3, 4, 14)
L21=[23, 38, 18]
L22=[45]
L2=L21 + pivot + L22 = (23, 38, 18, 42, 45)
A cette tape voici le nouvel arrangement de L :
L = [(2,3, 4, 14), 16, (23, 38, 18, 42, 45)]
etc...
Ainsi
de proche en proche en subdivisant le problme en deux sous-problmes, chaque tape nous
obtenons un pivot bien plac.
B) Spcification concrte
La suite (a
1
, a
2
, ... , a
n
) est range dans un tableau de dimension unT[...] en mmoire centrale.
Le processus de partionnement dcrit ci-haut (appel aussi segmentation) est le point central
du tri rapide, nous construisons une fonction Partition ralisant cette action .
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
308
Comme l'on appliquant la mme action sur les deux sous-listes obtenues aprs partition, la
mthode est donc rcursive, le tri rapide est alors une procdure rcursive.
B-1 ) Voici une spcification gnrale de la procdure de tri rapide :
Tri Rapide sur [a..b]
Partition [a..b] renvoie pivot & [a..b] = [x .. pivot']+[pivot]+[pivot'' .. y]
Tri Rapide sur [pivot'' .. y]
Tri Rapide sur [x .. pivot']
B-2) Voici une spcification gnrale de la fonction de partionnement :
La fonction de partionnement d'une liste [a..b] doit rpondre aux deux conditions
suivantes :
- renvoyer la valeur de l'indice not i d'un lment appel pivot qui est
bien plac dfinitivement : pivot = T[i],
- tablir un rarrangement de la liste [a..b] autour du pivot tel que :
[a..b] = [x .. pivot']+[pivot]+[pivot'' .. y]
[x .. pivot'] = T[G] , .. , T[i-1]
( o : x = T[G] et pivot' = T[i-1] ) tels que les T[G] , .. , T[i-1] sont tous infrieurs T[i] ,
[pivot'' .. y] = T[i+1] , .. , T[D]
( o : y = T[D] et pivot'' = T[i+1] ) tels que les T[i+1] , .. , T[D] sont tous suprieurs T[i] ,
Il est propos de choisir arbitrairement le pivot que l'on cherche placer, puis ensuite de
balayer la liste rarranger dans les deux sens (par la gauche et par la droite) en construisant
une sous-liste gauche dont les lments ont une valeur infrieure celle du pivot et une
sous-liste droite dont les lments ont une valeur suprieure celle du pivot .
1) Dans le balayage par la gauche, on ne touche pas un lment si sa valeur est infrieure
au pivot (les lments sont considrs comme tant alors dans la bonne sous-liste) on
arrte ce balayage ds que l'on trouve un lment dont la valeur est plus grande que celle
du pivot. Dans ce dernier cas cet lment n'est pas sa place dans cette sous-liste mais
plutt dans l'autre sous-liste.
2) Dans le balayage par la droite, on ne touche pas un lment si sa valeur est suprieure au
pivot (les lments sont considrs comme tant alors dans la bonne sous-liste) on arrte ce
balayage ds que l'on trouve un lment dont la valeur est plus petite que celle du pivot. Dans
ce dernier cas cet lment n'est pas sa place dans cette sous-liste mais plutt dans l'autre
sous-liste.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
309
3) on procde l'change des deux lments mal placs dans chacune des sous-listes :
4) On continue le balayage par la gauche et le balayage par la droite tant que les lments sont
bien placs (valeur infrieure par la gauche et valeur suprieure par la droite), en changeant
chaque fois les lments mal placs.
5) La construction des deux sous-listes est termine ds que l'on atteint (ou dpasse) le pivot.
Appliquons cette dmarche l'exemple prcdent : L = [ 4, 23, 3, 42, 2, 14, 45, 18, 38, 16 ]
- Choix arbitraire du pivot : l'lment le plus droite ici 16
- Balayage gauche :
4 < 16 => il est dans la bonne sous-liste, on continue
liste en cours de construction : [ 4, 16 ]
23 > 16 => il est mal plac il n'est pas dans la bonne sous-liste, on arrte le balayage gauche,
liste en cours de construction :[ 4, 23, 16 ]
- Balayage droite :
38 > 16 => il est dans la bonne sous-liste, on continue
liste en cours de construction : [ 4, 23, 16, 38 ]
18 > 16 => il est dans la bonne sous-liste, on continue
liste en cours de construction : [ 4, 23, 16, 18, 38 ]
45 > 16 => il est dans la bonne sous-liste, on continue
liste en cours de construction : [ 4, 23, 16, 45, 18, 38 ]
14 < 16 => il est mal plac il n'est pas dans la bonne sous-liste, on arrte le balayage droit,
liste en cours de construction : [ 4, 23, 16, 14, 45, 18, 38 ]
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
310
- Echange des deux lments mal placs :
[ 4, 23 , 16, 14 , 45, 18, 38 ] ----> [ 4, 14 , 16, 23, 45, 18, 38 ]
- On reprend le balayage gauche l'endroit o l'on s'tait arrt :
----------+----------------------------
[ 4, 14, 3 , 42, 2, 23, 45, 18, 38, 16 ]
3 < 16 => il est dans la bonne sous-liste, on continue
liste en cours de construction : [ 4, 14, 3 , 16 , 23, 45, 18, 38 ]
42 > 16 => il est mal plac il n'est pas dans la bonne sous-liste, on arrte de nouveau le
balayage gauche,
liste en cours de construction : [ 4, 14, 3, 42 , 16, 23, 45, 18, 38 ]
- On reprend le balayage droit l'endroit o l'on s'tait arrt :
-----------------+---------------------
[ 4, 14, 3, 42, 2 , 23, 45, 18, 38, 16 ]
2 < 16 => il est mal plac il n'est pas dans la bonne sous-liste, on arrte le balayage droit,
liste en cours de construction : [ 4, 14, 3, 42 , 16, 2, 23, 45, 18, 38 ]
- On procde l'change des deux lments mal placs :
[ 4, 14, 3, 42 , 16, 2 , 23, 45, 18, 38 ] ----> [ 4, 14, 3, 2 , 16, 42, 23, 45, 18, 38 ]
et l'on arrte la construction puisque nous sommes arrivs au pivot la fonction partition a
termin son travail elle a valu :
- le pivot : 16
- la sous-liste de gauche : L1 = [4, 14, 3, 2]
- la sous-liste de droite : L2 = [23, 45, 18, 38, 42]
- la liste rarrange : [ 4, 14, 3, 2, 16, 42, 23, 45, 18, 38 ]
Il reste recommencer les mmes oprations sur les parties L1 et L2 jusqu' ce que les
partitions ne contiennent plus qu'un seul lment.
C) Algorithme :
Global :Tab[min..max] tableau d'entier
fonction Partition( G , D : entier ) rsultat : entier
Local : i , j , piv , temp : entier
dbut
piv Tab[D];
i G-1;
j D;
repeter
repeter i i+1 jusqu Tab[i] >= piv;
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
311
repeter j j-1 jusqu Tab[j] <= piv;
temp Tab[i];
Tab[i] Tab[j];
Tab[j] temp
jusqu j <= i;
Tab[j] Tab[i];
Tab[i] Tab[d];
Tab[d] temp;
rsultat i
FinPartition
Algorithme TriRapide( G , D : entier );
Local : i : entier
dbut
si D > G alors
i Partition( G , D );
TriRapide( G , i-1 );
TriRapide( i+1 , D );
Fsi
FinTRiRapide
Nous supposons avoir mis une sentinelle dans le tableau, dans la premire cellule la plus
gauche, avec une valeur plus petite que n'importe qu'elle autre valeur du tableau.
Cette sentinelle est utile lorsque le pivot choisi alatoirement se trouve tre le plus petit
lment de la table /pivot = min (a1, a2, ... , an)/ :
Comme nous avons:
j , Tab[j] > piv , alors la boucle :
"repeter j j-1 jusqu Tab[j] <= piv ;"
pourrait ne pas s'arrter ou bien s'arrter sur un message d'erreur.
La sentinelle tant plus petite que tous les lments y compris le pivot arrtera la boucle et encore une fois vite
de programmer le cas particulier du pivot = min (a1, a2, ... , an).
D) Complexit :
Nous donnons les rsultats classiques et connus mathmatiquement (pour les dmonstrations
nous renvoyons aux ouvrages de R.Sedgewick & Aho-Ullman cits dans la bibliographie).
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
312
L'opration lmentaire choisie est la comparaison de deux cellules du tableau.
Comme tous les algorithmes qui divisent et traitent le problme en deux sous-problmes le
nombre moyen de comparaisons est en O(n.log(n)) que l'on nomme complexit moyenne. La
notation log (x) est utilise pour le logarithme base 2, log
2
(x).
L'exprience pratique montre que cette complexit moyenne en O(n.log(n)) n'est atteinte que
lorsque les pivots successifs divisent la liste en deux sous-listes de taille peu prs
quivalente.
Dans le pire des cas (par exemple le pivot choisi est systmatiquement chaque fois la plus
grande valeur) on montre que la complexit est en O(n
2
).
Comme la littrature a montr que ce tri tait le meilleur connu en complexit, il a t propos
beaucoup d'amliorations permettant de choisir un pivot le meilleur possible, des
combinaisons avec d'autres tris par insertion gnralement, si le tableau trier est trop petit.
Ce tri est pour nous un excellent exemple en n.log(n).illustrant la rcursivit.
E) Programme Delphi (tableau d'entiers) :
program TriQuickSort;
const N = 10; { Limite suprieure de tableau }
type TTab = array [0..N] of integer; { TTab : Type Tableau }
var Tab : TTab ;
function Partition ( G , D : integer) : integer;
var i , j : Integer;
piv, temp : integer;
begin
i := G-1;
j := D;
piv := Tab[D];
repeat
repeat i := i+1 until Tab[i] >= piv;
repeat j := j-1 until Tab[j] <= piv;
temp :=Tab[i];
Tab[i] :=Tab[j];
Tab[j] :=temp;
until j <= i;
Tab[j] := Tab[i];
Tab[i] := Tab[d];
Tab[d] := temp;
result := i;
end;{Partition}
Choix opration
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
313
procedure TriRapide( G, D : integer);
var i: Integer;
begin
if D>G then
begin
i := Partition( G , D );
TriRapide( G , i-1 );
TriRapide( i+1 , D );
end
end;{TriRapide}
procedure Initialisation(var Tab:TTab) ;
{ Tirage alatoire de N nombres de 1 100 }
var i : integer; { i : Indice de tableau de N colonnes }
begin
randomize;
for i := 1 to N do
Tab[i] := random(100);
Tab[0] := -Maxint ; // la sentinelle
end;
procedure Impression(Tab:TTab) ;
{ Affichage des N nombres dans les colonnes }
var i : integer;
begin
writeln('------------------------');
for i:= 1 to N do write(Tab[i] : 3, ' | ');
writeln;
end;
begin
Initialisation(Tab);
writeln('TRI RAPIDE');
writeln;
Impression(Tab);
TriRapide( 1 , N );
Impression(Tab);
writeln('----------------------');
end.
Rsultat de l'excution du programme prcdent :
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
314
E) Programme Java (tableau d'entiers) :
class ApplicationTriQSort
{
static int[] table = new int[21] ; // le tableau trier en attribut
/* Les cellules [0] et [20] contiennent
des sentinelles,
Les cellules utiles vont de 1 19.
(de 1 table.length-2)
*/
static void impression ( )
{
// Affichage sans les sentinelles
int n = table.length-2;
for ( int i = 1; i<=n; i++)
System.out.print(table[i]+" , ");
System.out.println();
}
static void initialisation ( )
{
// remplissage alatoire du tableau
int n = table.length-2;
for(int i = 1; i<=n; i++)
table[i] = (int)(Math.random()*100);
// Les sentinelles:
table[0] = -Integer.MAX_VALUE;
table[n+1] = Integer.MAX_VALUE;
}
// ----> Tri rapide :
static int partition (int G, int D )
{ // partition / Sedgewick /
int i, j, piv, temp;
piv = table[D];
i = G-1;
j = D;
do
{
do
i++;
while (table[i]<piv);
do
j--;
while (table[j]>piv);
temp = table[i];
table[i] = table[j];
table[j] = temp;
}
while(j>i);
table[j] = table[i];
table[i] = table[D];
table[D] = temp;
return i;
}
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
315
static void QSort (int G, int D )
{ // tri rapide, sous-programme rcursif
int i;
if(D>G)
{
i = partition(G,D);
QSort(G,i-1);
QSort(i+1,D);
}
}
public static void main(string[ ] args)
{
Initialisation ( );
int n = table.length-2;
System.out.println("Tableau initial :");
Impression ( );
QSort(1,n);
System.out.println("Tableau une fois tri :");
Impression ( );
}
}
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
316
Le tri par arbre
- Dfinitions prliminaires
- A) Spcification abstraite
- B) Spcification concrte
- C) Algorithme
- D) Complexit
- E) Programme Delphi
C'est un tri galement appel tri par tas (heapsort, en anglais). Il utilise une structure de donnes
temporaire dnomme "tas" comme mmoire de travail.
Dfinition - 1 / Arbre parfait :
c'est un arbre binaire dont tous les noeuds de chaque niveau sont prsents sauf ventuellement
au dernier niveau o il peut manquer des noeuds (noeuds terminaux = feuilles), dans ce cas
l'arbre parfait est un arbre binaire incomplet et les feuilles du dernier niveau doivent tre
regroupes partir de la gauche de l'arbre
.
un arbre parfait complet
Amputons l'arbre parfait prcdent de ses trois feuilles situes sur le bord droit, les cinq
premires feuilles de gauche ne changeant pas, on obtient toujours un arbre parfait mais il est
incomplet :
Dfinitions prliminaires
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
317
un autre arbre parfait incomplet
exemple d'arbre non parfait
Dfinition - 2 / Arbre partiellement ordonn :
C'est un arbre tiquet dont les noeuds appartiennent un ensemble muni d'une relation
d'ordre total (les nombres entiers, rels etc... en sont des exemples) tel que pour un noeud
donn tous ses fils ont une valeur suprieure ou gale celle de leur pre.
Exemple d'un arbre partiellement ordonn sur l'ensemble {20, 27,29, 30, 32, 38, 45, 45, 50,
51, 67 ,85 } d'entiers naturels :
Nous remarquons que la racine d'un tel arbre est toujours l'lment de l'ensemble
possdant la valeur minimum(le plus petit lment de l'ensemble), car la valeur de ce noeud
par construction est infrieure celle de ses fils et par transitivit de la relation d'ordre celles
de ses descendants c'est le minimum.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
318
Si donc nous arrivons ranger une liste d'lments dans un tel arbre le minimum de cette liste
est atteignable immdiatement comme racine de l'arbre.
Exemple d'un autre arbre partiellement ordonn sur le mme ensemble {20, 27,29, 30, 32, 38,
45, 45, 50, 51, 67 ,85 } d'entiers naturels (il n'y a pas unicit) :
Dfinition - 3 / Le tas :
On appelle tas un tableau reprsentant un arbre parfait partiellement ordonn.
C'est une variante de mthode de tri par slection o l'on parcourt le tableau des lments en
slectionnant et conservant les minimas successifs (plus petits lments partiels) dans un arbre parfait
partiellement ordonn.
A) Spcification abstraite
Nous supposons que les donnes a
1
, a
2
, ... , a
n
sont mises sous forme d'une liste (a
1
, a
2
, ... ,
a
n
), le principe du tri par tas est de parcourir la liste (a
1
, a
2
, ... , a
n
) en ajoutant chaque lment
ak dans un arbre parfait partiellement ordonn.
- L'insertion d'un nouvel lment a
k
dans l'arbre a lieu dans la dernire feuille vide de
l'arbre partir de la gauche (ou bien si le niveau est complet en recommenant un
nouveau niveau par sa feuille la plus gauche) et, en effectuant des changes tant que
la valeur de a
k
est infrieur celle de son pre.
- Lorsque tous les lments de la liste seront placs dans l'arbre, l'lment minimum "a
i
"
de la liste (a
1
, a
2
, ... , a
n
) se retrouve la racine de l'arbre qui est alors partiellement
ordonn.
Principe du tri par tas
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
319
- On recommence le travail sur la nouvelle liste (a
1
, a
2
, ... , a
n
) -{a
i
}(c'est la liste prcdente
prive de son minimum),
pour cela on supprime l'lment minimum ai de l'arbre pour le mettre dans la
liste trie puis,
on prend l'lment de la dernire feuille du dernier niveau et on le place
la racine.
On effectue ensuite des changes de contenu avec le fils dont le contenu est
infrieur, en partant de la racine, et en descendant vers le fils avec lequel on a
fait un change, ceci tant qu'il n'a pas un contenu infrieur ceux de ses deux
fils (ou de son seul fils) ou tant qu'il n'est pas une feuille.
- On recommence l'opration de suppression et d'changes ventuels jusqu' ce que
l'arbre ne contienne plus aucun lment.
B) Spcification concrte
La suite (a
1
, a
2
, ... , a
n
) est range dans un tableau une dimension T[...] correspondant au
tableau d'initialisation. Puis les lments de ce tableau sont ajouts et traits un par un dans un
arbre avant d'tre ajouts dans un tableau tri en ordre dcroissant ou croissant, selon le choix
de l'utilisateur.
Signalons qu'un arbre binaire parfait se reprsente classiquement par un tableau :
Si t est ce tableau, on a les rgles suivantes :
- t[1] est la racine :
- t[i div 2] est le pre de t[i] pour i > 1 :
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
320
- t[2 * i] et t[2 * i + 1] sont les deux fils, s'ils existent,
de t[i] :
- si p est le nombre de noeuds de l'arbre et si 2 * i = p,
t[i] n'a qu'un fils, t[p].
si i est suprieur p div 2, t[i] est une feuille.
Figures illustrant le placement des lments de la liste dans l'arbre
Exemple d'initialisation sur un tableau 15 lments :
Insertion du premier lment (le nombre 7) la racine de l'arbre :
Insertion du second lment (le nombre 27, 27 > 7 donc c'est un fils du noeud 7) :
Insertion du troisime lment (le nombre 41, 41 > 7 c'est un fils du noeud 7) :
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
321
Insertion du quatrime lment (le nombre 30, comme le niveau des fils du noeud 7 est
complet, 30 est plac automatiquement sur une nouvelle feuille d'un nouveau niveau, puis il
est compar son pre 27, 30 > 27 c'est donc un fils du noeud 27 il n'y a pas d'change ) :
Insertion du cinquime lment (le nombre 10) : L'insertion du nouvel lment 10 dans l'arbre
a lieu automatiquement dans la dernire feuille vide de l'arbre partir de la gauche, ici le fils
droit de 27 :
Puis 10 est compar son pre 27, cette fois 10 est plus petit que 27, il y a donc change des
places entre 27 et 10, ce qui donne un nouvel arbre :
Puis 10 est compar son nouveau pre 7, cette fois il n'y a pas d'change car 10 est plus
grand que 7.
Le processus continue avec l'lment suivant de la liste le nombre 31:
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
322
31 est automatiquement rang sur la premire feuille disponible gauche soit le fils gauche
de 41:
Puis 31 est compar son pre, comme 31 < 41 il y a change des valeurs, puis 31 est
compar son nouveau pre 7 comme 31 > 7 il n'y a plus d'change :
etc....
Supposons que l'arbre ait t construit sur les dix premiers lments du tableau et
observons maintenant comment l'lment minimum de la liste qui est le onzime
lment, soit le nombre 3, est rang dans l'arbre.
Voici l'tat de l'arbre avant introduction du nombre 3 (quatre niveaux de nuds) :
Le nombre 3 est introduit sur la premire feuille libre du niveau quatre :
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
323
Il est compar son pre le noeud 17, comme 3 < 17, il y a alors change :
Il est ensuite compar son nouveau pre le noeud 10, comme 3 < 10, il y a alors change :
Il est enfin compar son dernier pre (la racine de l'arbre), comme 3 < 7, il y a alors change
:
C'est l'lment 3 qui est maintenant la racine de l'arbre, comme les 4 lments suivants sont
plus grand que 3, ils seront rangs plus bas dans l'arbre (cf. figure ci-dessous) :
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
324
Conclusion sur le premier passage :
La liste initiale :
est finalement stocke ainsi :
Figures illustrant la suppression de la racine
Le nombre 3 est le plus petit lment, on le supprime de l'arbre et l'on prend l'lment de la
dernire feuille du dernier niveau (ici le nombre 25) et on le place la racine ( la place
qu'occupait le nombre 3)
ce qui donne comme nouvelle disposition :
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
325
et l'on recommence les changes ventuels en comparant la racine avec ses descendants :
le fils gauche 23 est infrieur 25 => change
Arrt du processus (33 > 25 et 30 > 25)
On obtient le deuxime plus petit lment la racine de l'arbre, ici le nombre 7.
Puis l' on continue "vider" ainsi l'arbre et dplaant les feuilles vers la racine et en
changeant les noeuds mal placs.
A la fin, lorsque l'arbre a t entirement vid, nous avons extrait chaque tape le plus petit
lment de chaque sous liste restante et nous obtenons les lments de la liste classs par
ordre croissant ou dcroissant selon notre choix (dans notre exemple si nous stockons les
minima successifs de gauche droite dans une liste nous obtiendrons une liste classe par
ordre croissant de gauche droite).
En rsum notre version de tri par tas comporte les tapes suivantes :
- initialisation : ajouter successivement chacun des n lments dans le tas t[1..p]; p
augmente de 1 aprs chaque adjonction . A la fin on a un tas de taille p = n.
- tant que p est plus grand que 1, supprimer le minimum du tas (p dcrot de 1), rorganiser
le tas, ranger le minimum obtenue la (p + 1)
ime
place.
On en dduit l'algorithme ci-dessous compos de 2 sous algorithmes Ajouter pour la
premire tape, et Supprimer pour la seconde.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
326
C) Algorithme :
Algorithme Ajouter
Entre P : entier ; x : entier // P nombre d'lments dans le tas, x lment ajouter
Tas[1..max] : tableau d'entiers // le tas
Sortie P : entier
Tas[1..max] // le tas
Local j, temp : entiers
dbut
P P + 1 ; // incrmentation du nombre d'lments du tas
j P ; // initialisation de j la longueur du tas (position de la dernire feuille)
Tas[P] x ; // ajout l'lment x la dernire feuille dans le tas
Tantque (j > 1) et (Tas[j] < Tas[j div 2]) faire ; // tant que l'on est pas arriv la racine et
que le "fils" est infrieur son "pre", on permute les 2 valeurs
temp Tas[j] ;
Tas[j] Tas[j div 2] ;
Tas[j div 2] temp ;
j j div 2 ;
finTant
FinAjouter
Algorithme Supprimer
Entre : P : entier // P nombre d'lments contenu dans l'arbre
Tas[1..max] : tableau d'entiers // le tas
Sortie : P : entier // P nombre d'lments contenu dans l'arbre
Tas[1..max] : tableau d'entiers // le tas
Lemini : entier // le plus petit de tous les lments du tas
Local i, j, temp : entiers ;
dbut
Lemini Tas[1] ; // retourne la racine (minimum actuel) pour stockage ventuel
Tas[1] Tas[P] ; // la racine prend la valeur de la dernire feuille de l'arbre
P P - 1 ;
j 1 ;
Tantque j <= (P div 2) faire
// recherche de l'indice i du plus petit des descendants de Tas[j]
si (2 * j = P ) ou (Tas[2 * j] < Tas[2 * j + 1])
alors i 2 * j ;
sinon i 2 * j +1 ;
Fsi;
// Echange ventuel entre Tas[j] et son fils Tas[i]
si Tlab[j] > Tlab[i] alors
temp Tlab[j] ;
Tlab[j] Tlab[i] ;
Tlab[i] temp ;
j i ;
sinon Sortir ;
Fsi;
finTant
FinSupprimer
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
327
Algorithme Tri_par_arbre
Entre Tas[1..max] // le tas
TabInit[1..max] // les donnes initiales
Sortie TabTrie[1..max]: tableaux d'entiers // tableau une fois tri
Local P : Entier // P le nombre d'lments trier
Lemin : entier // le plus petit de tous les lments du tas
dbut
P 0;
Tantque P < max faire
Ajouter(P,Tas,TabInit[P+1]); // appel de l'algorithme Ajouter
finTant;
Tantque P >= 1 faire
Supprimer(P,Tas,Lemin) ; // appel de l'algorithme Supprimer
TabTrie[max-P] Lemin ; // stockage du minimum dans le nouveau tableau
finTant;
Fin Tri_par_arbre
D) Complexit :
Cette version de l'algorithme construit le tas par n appels de la procdure Ajouter et effectue
les slections par n - 1 appels de la procdure supprimer.
Le cot et de l'ordre de comparaisons, au pire.
La complexit au pire en nombre de comparaisons est en O(n log n).
Le nombre d'changes dans le tas est major par le nombre de comparaisons et il est du mme
ordre de grandeur.
La complexit au pire en nombre de transferts du tri par tas est donc en O(n log n).
E) Programme Delphi (tableau d'entiers) :
program TriParArbre;
const Max =10; // nombre maximal d'lments du tableau
type TTab=array [1..Max] of integer; // TTab : Type Tableau
var Tas, TabInit, TabTrie : TTab; // Tas, tableau initial puis tableau
triTableau
P, Lemin : integer;
procedure Ajouter (var Tas : TTab; var P, x : integer);
var j, temp : integer ;
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
328
begin
P := P + 1 ;
J := P ;
Tas[P] := x ;
if j>1 then
While Tas[j] < Tas[j div 2] do
begin
temp := Tas[j] ;
Tas[j] := Tas[j div 2] ;
Tas[j div 2] := temp ;
j := j div 2 ;
if j<=1 then break;
end
end; // Ajouter
procedure Supprimer (var Tas:TTab; var P, Lemin : integer);
var i, j, temp : integer ;
begin
Lemin := Tas[1] ;
Tas[1] := Tas[P] ;
P := P - 1 ;
j := 1 ;
While j <= (P div 2) do
begin
if (2 * j = P ) or (Tas[2 * j] < Tas[2 * j + 1])
then i := 2 * j
else i := 2 * j +1 ;
if Tas[j] > Tas[i] then
begin
temp := Tas[j] ;
Tas[j] := Tas[i] ;
Tas[i] := temp ;
j := i ;
end
else break ;
end
end; // Supprimer
procedure Initialisation(var Tab:TTab) ;
// Tirage alatoire de Max nombres de 1 100
var i : integer; // i : Indice de tableau
begin
randomize;
for i := 1 to Max do
Tab[i] := random(100);
end;
procedure Impression(Tab:TTab) ;
// Affichage des Max nombres
var i : integer;
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
329
begin
writeln('---------------------');
for i:= 1 to Max do write(Tab[i] : 3, ' | ');
writeln;
end;
begin // TriParArbre
Initialisation(TabInit);
writeln('TRI PAR ARBRE');
writeln;
Impression(TabInit);
P:=0;
while p < Max do
Ajouter ( Tas, p, TabInit[p+1] );
while p >= 1 do
begin
Supprimer ( Tas, P, Lemin ) ;
TabTrie[Max-P]:=Lemin
end;
Impression(TabTrie);
writeln('----------------------');
readln
end. // TriParArbre
REMARQUE IMPORTANTE
Notons que dans la procdure nous avons traduit la condition de la boucle :
Tantque (j > 1) et (Tas[j] < Tas[j div 2]) faire
temp Tas[j] ;
Tas[j] Tas[j div 2] ;
Tas[j div 2] temp ;
j j div 2 ;
finTant
par les lignes de programmes suivantes :
if j>1 then
While Tas[j] < Tas[j div 2] do
begin
temp := Tas[j] ;
Tas[j] := Tas[j div 2] ;
Tas[j div 2] := temp ;
j := j div 2 ;
if j<=1 then break
end
ceci afin d'viter un incident d un effet de bord. Lorsque l'indice "j" prend par exemple la
valeur 1, l'indice "j div 2" vaut alors 0 et cette valeur n'est pas valide puisque l'indice de
tableau varie entre 1..Max.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
330
On peut pallier aussi d'une autre manire cet inconvnient en ajoutant une sentinelle "
gauche dans le tableau" en tendant la borne infrieure la valeur 0, les indices pouvant alors
varier entre 0..Max. On obtient une autre criture de la procdure "Ajouter" qui suit malgr
tout l'algorithme de prs :
type TTab=array [0..Max] of integer; // 0 est l'indice sentinelle
procedure Ajouter (var Tas : TTab; var P, x : integer);
var j, temp : integer ;
begin
P := P + 1 ;
J := P ;
Tas[P] := x ;
While (j > 1) et (Tas[j] < Tas[j div 2]) do
begin
temp := Tas[j] ;
Tas[j] := Tas[j div 2] ;
Tas[j div 2] := temp ;
j := j div 2 ;
end
end; // Ajouter
Rsultat de l'excution du programme prcdent :
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
331
3. Rechercher dans un tableau
Les tableaux sont des structures statiques contigus, il est facile de rechercher un lment fix
dans cette structure. Nous exposons ci-aprs des algorithmes lmentaires de recherche
utilisables dans des applications pratiques par le lecteur.
Essentiellement nous envisagerons la recherche squentielle qui convient lorsqu'il y a peu
d'lments consulter (quelques centaines), et la recherche dichotomique dans le cas o la
liste est trie.
3.1 Recherche dans un tableau non tri
Algorithme de recherche squentielle :
- Soit t un tableau d'entiers de 1..n lments non rangs.
- On recherche le rang (la place) de l'lment Elt dans ce tableau. L'algorithme
renvoie le rang (la valeur -1 est renvoye lorsque l'lment Elt n'est pas
prsent dans le tableau t)
- Complexit en O(n)
Nous proposons au lecteur 4 versions d'un mme algorithme de recherche squentielle. Le
lecteur adoptera une de ces versions en fonction des possibilits du langage avec lequel il
compte programmer sa recherche.
Version Tantque avec "et alors" (si le langage
dispose d'un oprateur et optimis)
Version Tantque avec "et" (oprateur et non
optimis)
i 1 ;
Tantque (i s n) et alors (t[i] = Elt) faire
i i+1
finTant;
si i s n alors rang i
sinon rang -1
Fsi
i 1 ;
Tantque (i < n) et (t[i] = Elt) faire
i i+1
finTant;
si t[i] = Elt alors rang i
sinon rang -1
Fsi
Version Tantque avec sentinelle en fin de tableau (rajout d'une cellule supplmentaire en fin
de tableau contenant systmatiquement l'lment rechercher)
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
332
Version Tantque avec sentinelle avec "et
alors"
Version Pour avec instruction de sortie
(conseille si le langage dispose d'un oprateur
Sortirsi )
t[n+1] Elt ; // sentinelle rajoute
i 1 ;
Tantque (i s n) et alors (t[i] = Elt) faire
i i+1
finTant;
si i s n alors rang i
sinon rang -1
Fsi
pour i 1 jusqu n faire
Sortirsi t[i] = Elt
fpour;
si i s n alors rang i
sinon rang -1
Fsi
3.2 Recherche dans un tableau tri
Spcifications d'un algorithme squentiel
- Soit t un tableau d'entiers de 1..n lments rangs par ordre croissant par exemple.
- On recherche le rang (la place) de l'lment Elt dans ce tableau. L'algorithme renvoie le
rang (la valeur -1 est renvoye lorsque l'lment Elt n'est pas prsent dans le tableau t)
On peut reprendre sans changement les versions de l'algorithme de recherche
squentielle prcdent travaillant sur un tableau non tri.
- Complexit moyenne en O(n)
On peut aussi utiliser le fait que le dernier lment du tableau est le plus grand lment et
s'en servir comme une sorte de sentinelle. Ci-dessous deux versions utilisant cette dernire
remarque.
Version Tantque Version pour
si t[n] < Elt alors rang -1
sinon
i 1 ;
Tantque t[i] < Elt faire
i i+1;
finTant;
si t[i] = Elt alors rang i
sinon rang -1 Fsi
Fsi
si t[n] < Elt alors rang -1
sinon
pour i 1 jusqu n-1 faire
Sortirsi t[i] > Elt // sortie de la boucle
fpour;
si t[i] = Elt alors rang i
sinon rang -1 Fsi
Fsi
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
333
Spcifications dun algorithme dichotomique
- Soit t un tableau d'entiers de 1..n lments rangs par ordre croissant par exemple.
- On recherche le rang (la place) de l'lment Elt dans ce tableau. L'algorithme renvoie le
rang (la valeur -1 est renvoye lorsque l'lment Elt n'est pas prsent dans le tableau t).
Au lieu de rechercher squentiellement du premier jusqu'au dernier, on compare
l'lment Elt chercher au contenu du milieu du tableau. Si c'est le mme, on
retourne le rang du milieu, sinon l'on recommence sur la premire moiti (ou la
deuxime) si l'lment recherch est plus petit (ou plus grand) que le contenu du
milieu du tableau.
- Complexit moyenne en O(log(n))
Soit un tableau au dpart contenant les lments (x
1
, x
2
, ... , x
n
)
On recherche la prsence de l'lment x dans ce tableau. On divise le tableau en 2 parties
gales :
Soit x est infrieur l' lment milieu et s'il est prsent il ne peut tre que dans la partie
gauche, soit x est suprieur l' lment milieu et s'il est prsent il ne peut tre que dans la
partie droite. Supposons que x < milieu nous abandonnons la partie droite et nous
recommenons la mme division sur la partie gauche :
On divise nouveau la partie gauche en deux parties gales avec un nouveau milieu :
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
334
Si x < milieu c'est la partie gauche qui est conserve sinon c'est la partie droite etc ...
Le principe de la division dichotomique aboutit la fin une dernire cellule dans laquelle
soit x = milieu et x est prsent dans la table, soit x = milieu et x n'est pas prsent dans la
table.
Version itrative du corps de cet algorithme :
bas, milieu, haut, rang : entiers
bas 1;
haut N;
Rang -1;
repter
milieu (bas + haut) div 2;
si x = t[milieu] alors
Rang milieu
sinon si t[milieu] < x alors
bas milieu + 1
sinon
haut milieu-1
fsi
fsi
jusqu ( x = t[milieu] ) ou ( bas haut )
Voici en Delphi une procdure traduisant la version itrative de cet algorithme :
procedure dichoIter(x:Elmt; table:tableau; var rang:integer);
{recherche dichotomique par itration dans table rang =-1 si pas trouv}
var
milieu:1..max;
g,d:0..max+1;
begin
g := 1;
d := max;
rang := -1;
while g <= d do
begin
milieu := (g+d) div 2;
if x = table[milieu] then
begin
rang := milieu;
exit
end
else
if x < table[milieu] then d := milieu-1
else g := milieu+1
end;
end;{dichoIter}
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) page
335
Dans le cas de langage de programmation acceptant la rcursivit (comme Delphi ), il est
possible d'crire une version rcursive de cet algorithme dichotomique.
Voici en Delphi une procdure traduisant la version rcursive de cet algorithme :
procedure dichoRecur(x:Elmt;table: tableau; g,d:integer; var rang:integer);
{ recherche dichotomique rcursive dans table
rang =-1 si pas trouv.
g , d: 0..max+1 }
var
milieu:1..max;
begin
if g<= d then
begin
milieu := (g+d) div 2;
if x = table[milieu] then rang := milieu
else
if x < table[milieu] then // la partie gauche est conserve
dichoRecur( x, table, g, milieu-1, rang )
else // la partie droite est conserve
dichoRecur( x, table, milieu+1, d, rang )
end
else rang := -1
end;{dichoRecur}
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) EXERCICES page
336
Exercices chapitre 3
Des exercices traits avec leur solution dtaille
Algorithmes et leur traduction en langage de programmation
Somme de 2 vecteurs
Fonctions boolennes
Variantes sur la factorielle
PGCD , PPCM de deux entiers
Nombres premiers
Nombres parfaits
Suite : racine carre - Newton
Inversion dun tableau
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) EXERCICES page
337
Des algorithmes
Somme de 2 vecteurs
Enonc :
Programme simple dutilisation des tableaux, on reprsente un vecteur de Z
n
dans un tableau un indice variant
de 1 n. Ecrire un programme LDFA additionnant 2 vecteurs de Z
n
dont les composantes sont lues au clavier.
Solution faisant apparatre les niveaux de dcomposition et l'algorithme associ
Niveau 1:
Algorithme Somme Vecteur
Entre: U,V deux vecteurs de Z
n
Sortie: W un vecteur de Z
n
Local: i e N
dbut
lire(U,V);
W U+V ;
ecrire (W)
FinSommeVecteur
Un vecteur de Z
n
est dfini par ses coordonnes : U(U
1
, U
2
, , U
n
) ; V(V
1
, V
2
, , V
n
) etc
Action < W = U+V > :
i , 1 s i s n / W
i
= U
i
+ V
i
Action < Lire ( U,V ) > :
i , 1 s i s n / lire U
i
et V
i
Action < Ecrire(W) > :
i , 1 s i s n / ecrire W
i
Description :
Pour i 1 jusqu n Faire
W
i
U
i
+ V
i
Fpour;
Description :
Pour i 1 jusqu n Faire
lire(U
i
, V
i
)
Fpour;
Description :
Pour i 1 jusqu n Faire
ecrire(W
i
)
Fpour;
Niveau 2 :
dbut
< lire(u,v) >
Pour i 1 jusqu n Faire
W
i
U
i
+ V
i
Fpour;
< ecrire(w) >
FinSommeVecteur
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) EXERCICES page
338
dbut
Pour i 1 jusqu n Faire
lire(U
i
, V
i
)
Fpour;
W = U+V
Pour i 1 jusqu n Faire
ecrire(W
i
)
Fpour;
FinSommeVecteur
programsomme_vecteur;
const n =3;
type
intervalle=1..n;
vecteur = array[intervalle] of integer;
var
U,V,W:vecteur;
i:intervalle;
begin
for i:=1 to n do readln (U[i],V[i]);
for i:=1 to n do W[i]:=U[i]+V[i];
for i:=1 to n do writeln(W[i]);
end.
Algorithme Somme Vecteur
Entre: U,V deux vecteurs de Z
n
Sortie: W un vecteur de Z
n
Local: i e N
dbut
pour i 1 jusqu n faire
lire(Ui , Vi )
Fpour;
pour i 1 jusqu n faire
Wi Ui + Vi
Fpour;
pour i 1 jusqu n faire
ecrire(Wi)
Fpour;
fin //sommevecteur
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) EXERCICES page
339
Fonctions boolennes
Enonc :
Programme simple d'criture de deux fonctions de calcul des deux connecteurs logiques, le et boolen et le ou
boolen par application des proprits suivantes :
X et Faux = Faux
X et Vrai = X
X ou Vrai = Vrai
X ou Faux = X
Solution en Ldfa avec les traductions de chaque fonction en Delphi-Pascal et en Java
LDFA LDFA
Algorithme LeEt
// un Et logique
Entre: x , y e Boolens
Sortie: resultat e Boolens
debut
si x = Faux alors
resultat Faux
sinon
resultat y
fsi
fin // LeEt
Algorithme LeOu
// un Ou logique
Entre: x , y e Boolens
Sortie: resultat e Boolens
debut
si x =Vrai alors
resultat Vrai
sinon
resultat y
fsi
fin // LeOu
DELPHI-Pascal DELPHI-Pascal
function Et(x,y : Boolean):Boolean;
begin
if x=faux then
result := false
else
result := y
end;
function Ou(x,y : Boolean):Boolean;
begin
if x=true then
result := true
else
result := y
end;
Java Java
boolean Et ( boolean x , boolean y )
{
if ( x == false )
return false ;
else
return y ;
}
boolean Ou ( boolean x , boolean y )
{
if ( x == true )
return true ;
else
return y ;
}
On pourra utiliser les raccourcis d'criture suivants pour un algorithme-fonction :
Algorithme LeEt
Entre: x , y e Boolens
Sortie: resultat e Boolens
Algorithme LeOu
Entre: x , y e Boolens
Sortie: resultat e Boolens
Fonction LeEt (x , y: Boolens) : resultat Boolens Fonction LeOu (x , y: Boolens) : resultat Boolens
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) EXERCICES page
340
Variantes sur la factorielle
Enonc : Algorithme de calcul de la factorielle d'un entier n! =n.(n-1)! en utilisant diffrentes instructions de
boucles.
Solution en Ldfa
par boucle tantque..ftant par boucle pourjusqu
Algorithme Factor
Entre: n e Entier*
Sortie: fact e Entier*
Local: i e N
dbut
lire(n) ;
fact 1;
i 2 ;
Tantque i <= n Faire
fact fact * i ;
i i + 1 ;
Ftant;
Ecrire (n ,! = , fact );
Fin // Factor
Algorithme Factor
Entre: n e Entier*
Sortie: fact e Entier*
Local: i e N
dbut
lire(n) ;
fact 1;
Pour i 2 jusqu n Faire
fact fact*i ;
Fpour;
Ecrire (n ,! = , fact );
Fin // Factor
par boucle repeter.... jusqua par rcursivit partir de la formule : n! =n.(n-1)!
Algorithme Factor
Entre: n e Entier*
Sortie: fact e Entier*
Local: i e Entier
dbut
lire(n) ;
fact 1;
i 2 ;
Repeter
fact fact * i ;
i i + 1 ;
jusqu i > n ;
ecrire(n ,! = , fact );
fin // Factor
Algorithme fact_recur
utilise Fonction fact
debut
ecrire ('5! =',fact(5))
fin // fact_recur
Fonction fact (n:entier) : resultat entier
debut
si n = 0 alors resultat 1
sinon resultat fact (n - 1) * n
fsi
fin // fact
program Factor;
var n , fact , i :integer ;
begin
readln(n);
fact:=1;
i:=2;
repeat
fact:=fact*i;
i:=i+1
until i > n ;
writeln(n ,'! = ', fact)
end.
program Factor;
var n:integer;
function fact (n : integer ) : integer ;
begin
if n=0 then result:=1
else result:=fact(n-1)*n
end;// fact
begin
readln(n);
writeln(n ,'! = ', fact(n));
end.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) EXERCICES page
341
PGCD , PPCM de deux entiers
Enonc : Ecrire des programmes LDFA donnant le pgcd et le ppcm de 2 entiers naturels.
Le pgcd de 2 entiers non nuls est le plus grand diviseur commun ces deux entiers.
Exemple : 35 et 21 ont pour pgcd 7, car 35 = 7*5 et 21 = 7*3,
Le ppcm de 2 entiers non nuls est le plus petit commun multiple ces deux entiers.
Exemple : 35 et 21 ont pour ppcm 105, car 105 =3*35 et 105=5*21.
Solution du pgcd faisant apparatre les niveaux de dcomposition et l'algorithme associ
La mthode employe pour valuer le pgcd de 2 entiers, se dnomme l'algorithme d'Euclide ou encore la
division par les restes successifs. Soit le calcul du pgcd de 35 et 21 : on divise 35 par 21, puis 21 par le reste 14,
puis 14 par le nouveau reste 7etcLe processus s'arrte lorsque le dernier reste est nul, le pgcd est alors le
prcdent reste non nul
Le dernier reste non nul tant 7, le pgcd de 35 et 21 est donc 7. D'une manire gnrale, pour calculer le pgcd de
deux entiers a et b nous divisons le plus grand par le plus petit, chacun de ces deux entiers est reprsent par une
variable a e N et b e N, nous classons systmatiquement les contenus de ces variables en mettant dans a le
plus grand des deux entiers et dans b le plus petit des deux.
Deux actions sont utilises pour calculer le pgcd de 2 entiers.
Niveau 1:
Algorithme CalculPgcd
Entre: a , b e N*
2
Sortie: pgcd e N
Local: r , t e N
2
dbut
< min(a,b) dans b, max dans a >;
< divisions par restes successifs >
FinCalculPgcd
Action < min(a,b) dans b, max dans a >: Action < divisions par restes successifs >:
Description :
Si b>a Alors
< change a et b >
Fsi;
Description :
Rpter
< r = reste (a par b) , division >
jusqu r=0;
pgcd a;
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) EXERCICES page
342
Niveau 2 :
Algorithme CalculPgcd
Entre: a , b e N*
2
Sortie: pgcd e N
Local: r , t e N
2
dbut
Si b>a Alors
< change a et b >
Fsi;
Rpter
< r = reste (a par b) , division >
jusqu r=0;
FinCalculPgcd
Action < change a et b > Action < r = reste (a par b) , division >
Description :
t a ;
a b ;
b t
Description :
r a mod b ;
a b ;
b r
Niveau 3 :
Algorithme CalculPgcd
Entre: a , b e N*
2
Sortie: pgcd e N
Local: r , t e N
2
dbut
Si b>a Alors
t a ;
a b ;
b t
Fsi;
< divisions par restes >
FinCalculPgcd
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) EXERCICES page
343
Ce qui donne finalement en dveloppant les branches de l'arbre jusqu'au niveau 3 :
Algorithme CalculPgcd
Entre: a ,b e N*
2
Sortie: pgcd e N
Local: r , t e N
2
dbut
lire(a,b);
Si b>a Alors
t a ;
a b ;
b t
Fsi;
Rpter
r a mod b ;
a b ;
b r
jusqu r=0;
pgcd a;
ecrire(pgcd)
FinCalculPgcd
programcalcul_Pgcd;
var
a , b : integer;
pgcd, r, t : integer;
begin
readln(a,b);
if b>a then
begin
t := a ;
a := b ;
b := t
end;
repeat
r := a mod b ;
a := b ;
b := r
until r=0;
pgcd:= a;
writeln(pgcd)
end.
Solution du calcul du ppcm de deux entiers sous forme d'un algorithme-fonction
La mthode employe pour valuer le ppcm de 2 entiers a et b ( b <a )est simple :
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) EXERCICES page
344
Nous valuons tous les multiples de b par ordre croissant (2b, 3b, ) et nous arrtons le calcul ds qu'un
multiple est divisible par a (si a et b sont premiers entre eux le ppcm est gal leur produit) :
Fonction ppcm (a,b:entier) rsultat entier;
local : n , p eentier
debut
p b;
n 1;
tantque (n <= a) et (p Mod a<>0) faire
p b * n;
n n + 1;
ftant
rsultat p
Fin // ppcm
program calcul_ppcm;
var
a, b, p:integer;
function ppcm (a,b:integer):integer;
var
k,p:integer;
begin
p:=b;
k:=1;
while (k<= a)and(p mod a<>0) do
begin
p:= b * k;
k:= k + 1;
end;
result:=p
end;
begin
a:= 125;
b:= 45;
p:= ppcm(a, b);
writeln('Calcul du ppcm :');
writeln('a=', a,' b=', b,' => ppcm=', p)
end.
class ApplicationPpcm {
public static void main(String[ ] args ) {
int a,b,p;
a=125;
b=45;
p=ppcm(a,b);
System.out.println("Calcul du ppcm :");
System.out.println("a="+a+" b="+b+" => ppcm="+p);
}
static int ppcm (int a , int b)
{
int n=1 , p=b;
while((n <= a)&(p %a !=0))
{
p= b * n;
n ++;
}
return p ;
}
/* Autre version avec un for sans aucun corps. Le code est
plus compact, mais il est moins lisible !
*/
static int ppcm (int a , int b)
{
int p=b;
for(int n=1; (n<=a)&(p%a!=0); n++,p=b*n);
return p ;
}
}
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) EXERCICES page
345
Nombres premiers
Enonc : Un nombre entier est premier sil nest divisible que par 1 et par lui-mme.
Exemple : 17 , 19, 31 sont des nombres premiers.
Ecrire un programme LDFA donnant les n premiers nombres premiers.
Solution faisant apparatre les niveaux de dcomposition et l'algorithme associ
Deux actions sont utilises pour calculer les nombres premiers,
elles correspondent chacune une branche de l'arbre.
Niveau 1:
Algorithme Premier
Entre: n e N
Sortie: x e N
Local: Est_premier e {Vrai , Faux}
Divis , compt e N
2
dbut
lire(n);
Tantque(compt < n) Faire
< recherche primalit de x >;
< comptage si x est premier >
Ftant
FinPremier
Action < recherche primalit de x > Action < comptage si x est premier >
Description :
Rpter
< x est-il divisible ?>
jusqu < non premier, ou plus de diviseurs>
Description :
Si Est_premier =Vrai Alors
<on ecrit x et on le compte>
Fsi;
<on passe au x suivant>
Etude de la branche gauche de l'arbre au niveau 2 :
Niveau 2 :
dbut
lire(n);
Tantque (compt < n) Faire
Rpter
< x est-il divisible ?>
jusqu < plus de diviseurs>
< comptage si x est premier >
Ftant
FinPremier
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) EXERCICES page
346
Etude de la branche gauche de l'arbre au niveau 3 :
Action < x est-il divisible ?> Action < non premier, ou plus de diviseurs>
Description :
Si x mod divis=0 Alors
Est_premier Faux
Sinon
divis divis+1
Fsi
Description :
(divis > n-1)
ou
(Est_premier=Faux)
Etude de la branche droite de l'arbre au niveau 2 :
Niveau 2 :
dbut
lire(n);
Tantque (compt < n) Faire
< recherche primalit de x >;
Si Est_premier =Vrai Alors
< Afficher x >
Fsi;
<on passe au x suivant>
Ftant
FinPremier
Etude de la branche droite de l'arbre au niveau 3 :
Rpter
Si x mod divis=0 Alors
Est_premier Faux
Sinon
divis divis+1
Fsi
jusqu (divis > x-1)ou (Est_premier=Faux);
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) EXERCICES page
347
Action < Afficher x > Action <on passe au x suivant>
Description :
ecrire(x);
compt compt+1
Description :
x x+1
Niveau 3 :
Algorithme Premier
Entre: n e N
Sortie: x e N
Local: Est_premier e {Vrai , Faux}
Divis , compt e N
2
dbut
lire(n);
Tantque (compt < n) Faire
< recherche primalit de x >;
Si Est_premier =Vrai Alors
ecrire(x);
compt compt+1
Fsi;
x x+1
Ftant
FinPremier
Version finale complte de l'algorithme sa traduction en Delphi
Algorithme Premier
Entre: n e N
Sortie: x e N
Local: Est_premier e {Vrai , Faux}
Divis , compt e N
2
dbut
lire(n);
compt 1;
ecrire(2);
x 3;
Tantque(compt < n) Faire
divis 2;
Est_premier Vrai;
Rpter
Si x mod divis=0 Alors Est_premier Faux
Sinon divis divis+1
Fsi
jusqu (divis > x-1)ou (Est_premier=Faux);
Si Est_premier =Vrai Alors
ecrire(x);
compt compt+1
Fsi;
x x+1
Ftant
FinPremier
programPremier;
var
n,nbr,divis,compt:integer;
Est_premier:boolean;
begin
write('Combien de nombres premiers : ');
readln(n);
compt:=1;
writeln(2);
nbr:= 3;
while (compt < n) do
begin
divis:= 2;
Est_premier:= true;
repeat
if nbr mod divis=0 then Est_premier:= false
else divis:= divis+1
until (divis > nbr div 2)or (est_premier=false);
if Est_premier=true then
begin
writeln(nbr);
compt:= compt+1
end;
nbr:= nbr+1
end
end.
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) EXERCICES page
348
Nombres parfaits
Enonc : Un nombre est dit parfait sil est gal la somme de ses diviseurs 1 compris.
Exemple : 6 = 1+2+3 , est parfait
Ecrire un programme LDFA donnant les n premiers nombres parfaits.
Solution faisant apparatre les niveaux de dcomposition et l'algorithme associ
Deux actions sont utilises pour calculer les nombres parfaits,
elles correspondent chacune une branche de l'arbre.
Niveau 1:
Algorithme Parfait
Entre: n e N
Sortie: nbr e N
Local: som, k, compt e N
3
dbut
Tantque (compt < n) Faire
< somme des diviseurs de nbr >;
< nbr est parfait >
Ftant
FinParfait
Action < somme des diviseurs de nbr > Action < nbr est parfait >
Description :
calcul de la somme des diviseurs du
nombre : nbr
Pour k 2 jusqu nbr-1 Faire
< cumul, si k divise nbr >
Fpour
Description :
lorsque le nombre nbr est reconnu comme parfait,
il doit tre compt, puis affich lcran
< nbr est parfait si nbr = som >
< comptage >
Etude de la branche gauche de l'arbre au niveau 2 :
Niveau 2 :
Dbut
Tantque (compt < n) Faire
pour k 2 jusqu nbr-1 Faire
< cumul des diviseurs >
Fpour;
< nbr est parfait si nbr=som >
< comptage >
Ftant
FinParfait
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) EXERCICES page
349
Etude de la branche gauche
de l'arbre au niveau 3 :
Etude de la branche droite de l'arbre au niveau 2 :
Niveau 2 :
dbut
Tantque (compt < n) Faire
< somme des diviseurs de nbr >;
< test nbr parfait ? >
< comptage >
Ftant
FinPremier
Action < test nbr parfait ? > Action < comptage >
Description :
le nombre nbr est parfait sil est gal la
somme calcule :
Si som=nbr Alors
ecrire(nbr) ;
compt compt+1;
Fsi;
Description :
Puis lon passe au nombre suivant
nbr nbr+1
Tantque (compt < n) Faire
pour k 2 jusqu nbr-1 Faire
Si nbr mod k = 0 Alors
som som + k
Fsi
Fpour
< nbr est parfait si nbr=som >
< comptage >
Ftant
Action < cumul des diviseurs, (si k divise nbr) >
__________________________________________________________________________
on cumule k dans la variable som (somme des diviseurs) du
nombre nbr lorsque k divise effectivement nbr.
Si nbr mod k = 0 Alors
som som + k
Fsi
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) EXERCICES page
350
Etude de la branche droite de l'arbre au niveau 3 :
Version finale complte de l'algorithme sa traduction en Delphi
Algorithme Parfait
Entre: n e N
Sortie: nbr e N
Local: som, k, compt e N
3
dbut
lire(n);
compt 0;
nbr 2;
Tantque (compt < n) Faire
som 1;
Pour k 2 jusqu nbr-1 Faire
Si nbr mod k = 0 Alors
som som + k
Fsi
Fpour ;
Si som=nbr Alors
ecrire(nbr) ;
compt compt+1;
Fsi;
nbr nbr+1
Ftant
FinParfait
programParfait;
var
n, nbr : integer;
som, k, compt : integer;
begin
readln(n);
compt := 0;
nbr := 2;
while (compt < n) do
begin
som:= 1;
for k:= 2 to nbr-1 do
if nbr mod k=0 then
som := som + k ;
if som=nbr then
begin
writeln(nbr);
compt:= compt+1;
end ;
nbr:= nbr+1
end
end.
Si som=nbr Alors
ecrire(nbr) ;
compt compt+1;
Fsi;
nbr nbr+1
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) EXERCICES page
351
Suite : racine carre - Newton
Enonc : Etude dune suite convergente de la forme U
n
= f(U
n-1
)
Ecrire un programme LDFA proposant une tude simple de la suite U
n
suivante (mthode de Newton) :
U
n
= 1/2(U
n-1
+ X/ U
n-1
) X>0
La suite U
n
converge vers le nombre \X (la racine carr de X), le programme doit effectuer :
1 le calcul du terme de rang n donn par lutilisateur,
2 le calcul jusqu' une prcision relative Epsilon fixe
Solution faisant apparatre les niveaux de dcomposition et l'algorithme associ
Deux actions sont utilises pour effectuer les calculs demands,
elles correspondent chacune une branche de l'arbre.
Niveau 1:
Algorithme Newton
Entre: n e N*
x e R*
c e R (c e [0,1] )
Sortie: u e R
Local: v e R
i e N
dbut
<calcul du terme de rang n>;
<calcul de la limite la prcision c >
FinNewton
Action <calcul du terme de rang n> Action <calcul de la limite la prcision c >
Description :
Pour i 1 jusqu n Faire
< u(n+1) [u(n)+x/u(n)]/2 >
Fpour;
Description :
Rpter
<* u(n+1)=[u(n)+x/u(n)]/2 , prcision *>
jusqu <* prcison < c *>
Etude de la branche gauche de l'arbre au niveau 2 :
Niveau 2:
dbut
Eps 10
-4
;
n 10;
lire(x);
Pour i 1 jusqu n Faire
< u(n+1) [u(n)+x/u(n)]/2 >
Fpour;
ecrire(u);
<calcul de la limite la prcision c >
FinNewton
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) EXERCICES page
352
Etude de la branche gauche de l'arbre au niveau 3 :
Dveloppement de la branche droite de l'arbre jusqu'au niveau 3 :
Niveau 3:
dbut
Eps 10
-4
;
n 10;
lire(x);
Pour i 1 jusqu n Faire
v u;
u (u + x/u)/2 ;
Fpour;
ecrire(u);
Rpter
v u;
u (u + x/u)/2 ;
jusqu | (u-v)/v | < Eps;
ecrire(u)
FinNewton
Version finale complte de l'algorithme sa traduction en Delphi
Algorithme Newton
Entre:
n eN* , x e R* , c e R (c e [0,1] )
Sortie: u e R
Local: v e R , i e N
dbut
Eps 10
-4
;
n 10;
lire(x);
// calcul du terme de rang n donn:
u (1 + x)/2 ;
Pour i 1 jusqu n Faire
u (u + x/u)/2 ;
Fpour;
ecrire(u);
programNewton;
const
Eps=1E-4;
n=10;
var
u,v,x : real ;
i : integer ;
begin
readln(x);
// calcul du terme de rang n donn:
u:=(1+x)/2;
for i:= 1 to n do
u:= (u + x/u)/2 ;
writeln(u);
Action < u(n+1) [u(n)+x/u(n) ]/2 >
______________________________________________________
v u;
u (u + x/u)/2 ;
Niveau 3:
dbut
Eps 10
-4
;
n 10;
lire(x);
Pour i 1 jusqu n Faire
v u;
u (u + x/u)/2 ;
Fpour;
ecrire(u);
<calcul de la limite la prcision c >
FinNewton
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) EXERCICES page
353
suite
//calcul jusqu' une prcision Epsilon fixe
u (1 + x)/2 ; { rinitialisation }
Rpter
v u;
u (u + x/u)/2 ;
jusqu | (u-v)/v | < Eps;
ecrire(u)
FinNewton
//calcul jusqu' une prcision Epsilon fixe
u:=(1+x)/2;
repeat
v:= u;
u:= (u+x/u)/2
until abs((u-v)/v ) < eps;
writeln(u)
end.
import Readln;
class Newton
{
public static void main (String [ ] arg) {
final double Eps=1E-4;
int n=10;
double u,v,x;
x = Readln.undouble();
// calcul du terme de rang n donn:
u = (1+x)/2;
for(int i=1;i<=n;i++)
u = (u + x/u)/2 ;
System.out.println("1) aprs "+n+" termes: "+u);
//calcul jusqu' une prcision Epsilon fixe:
u=(1+x)/2;
do
{
v = u;
u = (u+x/u)/2;
}
while(Math.abs((u-v)/v ) >= Eps);
System.out.println("2) la prcision "+Eps+": "+u);
}
}
Les bases de linformatique - programmation - ( rv. 04.01.2005 ) EXERCICES page
354
Inversion dun tableau
Enonc : Autre programme simple dutilisation des tableaux, crire un programme LDFA inversant le contenu
dun tableau n lments entiers dj rempli, on crira le contenu du tableau avant inversion, puis son contenu
aprs inversion.
Solution en Ldfa avec les traductions de chaque fonction en Delphi-Pascal et en Java
Algorithme InverseTable
Global: Table; vecteur de N
n
Local: temp e N, i e N
( i e [1 , Max] )
dbut
{remplissage alatoire du tableau}
Pour i 1 jusqu Max Faire
ecrire (Table
i
)
Fpour;
Pour i 1 jusqu Ent[Max/2] Faire
Temp Table
i ;
Table
i
Table
Max - i + 1
;
Table
Max - i + 1
Temp
Fpour;
Pour i 1 jusqu Max Faire
ecrire (Table
i
)
Fpour;
FinInverseTable
Ent[p] reprsente la partie entire de p
programinverse_tableau;
const
Max=10;
type
intervalle=1..Max;
Tableau=array[intervalle] of integer;
var
Table:Tableau;
i:intervalle;
Temp:integer;
begin
{remplissage alatoire du tableau}
for i:=1 to Max do
Table[i]:=random(1000);
{voir le contenu du tableau avant opration : }
for i:=1 to Max do
writeln('i=',i:2,':',Table[i]:4);
for i:=1 to Max div 2 do
begin
Temp:=Table[i];
Table[i]:=Table[Max-i+1];
Table[Max-i+1]:=Temp
end;
writeln('-----------------');
{voir le contenu du tableau aprs opration : }
for i:=1 to Max do
writeln('i=',i:2,':',Table[i]:4);
end.
class InvTab{
public static void main (String [ ] arg) {
final int Max=6;
long[ ]table= new long[Max+1];
//remplissage alatoire du tableau
for(int i=0;i<=Max;i++)
table[i] = Math.round(Math.random( )*100);
//voir le contenu du tableau avant opration
for(int i=0;i<=Max;i++)
System.out.println("table["+i+"] = "+
table[i]);
for(int i=0;i<=Max/2;i++) {
long Temp=table[i];
table[i]=table[Max-i];
table[Max-i]=Temp;
}
}
}