Méthodologie de programme et algorithmes
Méthodologie de programme et algorithmes
2
1.1. Phase 1 : Conception fondamentale ou analyse des besoins :.................................................................................2
1.2. Phase 2 : Conception détaillée ou Spécification:.....................................................................................................2
1.3. Phase 3 : Codage......................................................................................................................................................4
1.4. Phase 4 : Intégration.................................................................................................................................................4
1.5. Phase 5 : Validation - Tests.....................................................................................................................................4
1.6. Phase 6: Exploitation..............................................................................................................................................4
2. ALGORITHMES..........................................................................................................................................................5
2.1. Définition.................................................................................................................................................................5
2.2. Exemple : Calcul d’interêt.......................................................................................................................................5
2.3. Méthodologie...........................................................................................................................................................6
2.4. Formalisation de l’algorithme..................................................................................................................................6
2.5. Langage de description............................................................................................................................................7
2.6. Exemple : Addition..................................................................................................................................................8
2.7. Exemple : Robot......................................................................................................................................................8
2.8. Exercice a faire : Raffinement.................................................................................................................................9
3. LA SEQUENCE............................................................................................................................................................9
3.1. Instructions...............................................................................................................................................................9
3.2. les instructions de lecture (d'entrée) notées:............................................................................................................9
3.4. les instructions d'assignation (d'affectation) représentées par...............................................................................10
3.5. Exemples................................................................................................................................................................10
3.6. Déclaratives............................................................................................................................................................10
3.7. Exo a faire ……………….....................................................................................................................................11
4. LES STRUCTURES REPETITIVES.........................................................................................................................11
4.1. Introduction............................................................................................................................................................11
4.2. La boucle « tant que »............................................................................................................................................11
4.3. Exemple de calcul de PGCD..................................................................................................................................12
4.5. La boucle " pour"...................................................................................................................................................14
4.7. La boucle " répéter ... jusqu'à "..............................................................................................................................16
4.8. Exercices................................................................................................................................................................16
4.9. Le choix multiple...................................................................................................................................................16
4.10. Exercices...........................................................................................................................................................17
5. LES TABLEAUX.......................................................................................................................................................17
5.1. Notion de tableau...................................................................................................................................................17
5.2. Exemple.................................................................................................................................................................18
5.3. Parcours partiel d'un tableau..................................................................................................................................19
5.4. Exemple.................................................................................................................................................................19
5.5. Parcours imbriqués.................................................................................................................................................20
5.6. Exemple.................................................................................................................................................................20
5.7. Tableaux multidimensionnels................................................................................................................................20
5.8. Tableaux à deux dimensions..................................................................................................................................21
5.9. Exemple : calcul de la somme...............................................................................................................................21
5.10. Recherche dichotomique..................................................................................................................................22
5.11. Exemple............................................................................................................................................................22
5.12. Une technique de tri d’un tableau....................................................................................................................22
5.13. Exercices...........................................................................................................................................................24
5.14. Exercices...........................................................................................................................................................25
5.15. Travaux dirigés.................................................................................................................................................27
5.16......................................................................................................................................................................................... 34
6. Fonctions et procédures............................................................................................................................................41
6.1. Définition...............................................................................................................................................................41
6.2. Exemple : Pseudo-code – Tri Bull.........................................................................................................................42
7. Les structures de données............................................................................................................................................43
1
1. Méthodologie de conception d’un programme
L'absence de cette méthodologie conduit le plus souvent à des défaillances du programme. En effet,
on constate généralement que 60% des erreurs rencontrées lors de la mise en oeuvre d'un
programme sont des erreurs de conception algorithmique, et 40% de ces erreurs ne sont détectées
que pendant ou après les tests de validation.
Elle représente le point de départ de la phase de conception, elle permet à partir d'un cahier des
charges, d'élaborer les spécifications fonctionnelles du l'application (programmes) et de définir de
façon fonctionnelle, le comportement de votre application (par quel processus, dans quel domaine
d'application ?). FORMULER LE PROBLEME
L'objectif de cette phase est de définir, de façon aussi précise que possible la spécification des
données et actions sur ces données intervenant dans votre application (programmes)
La spécification : c'est la description d'une action en terme d'état initial et d'état final.
Action spécifiée : abstraction sur laquelle on peut raisonner.
Les notions d'état initial et final ne pouvant s'exprimer qu'en termes d'état des objets manipulés par
les programmes (algorithmes).
Après avoir spécifié les données et vérifié qu'elles correspondent globalement au cahier des charges
défini dans la phase 1, on peut entreprendre la construction d'une solution.
La figure présentée ci-dessous illustre les étapes nécessaires à la mise en oeuvre d'une solution
2
La phase de conception détaillée est répartie en trois étapes :
¨ Une étape initiale de modélisation, où le problème à résoudre est représenté par un modèle
formel.
¨ Une étape de raisonnement rigoureux, où les règles de raisonnements sont surtout utilisées pour
construire une suite de modèles (modèles intermédiaires). Chaque modèle caractérise un élément de
solution.
¨ Une étape d'adaptation au problème initial, où une solution de ce problème est dérivée de la
solution formelle trouvée au niveau du modèle.
Il faut noter que ces étapes illustrent la démarche scientifique de conception quel que soit le
domaine d'application.
Le codage est l'écriture d'un module dans un langage de programmation afin de le rendre
exécutable.
[Link] 4 : Intégration
Le rôle de la phase d'intégration est de traduire les spécifications du cahier des charges définitif en
instructions exécutables. L'intégration doit être réalisée module par module: la mise en oeuvre
progressive des unités de traitement (module ou programme) facilite la mise au point en isolant les
erreurs.
3
La construction doit être structurée pour permettre le test des modules en adoptant une approche
descendante. Les programmes sont ainsi testés individuellement, puis intégrés dans le contexte de
l'application, et toute erreur reste donc facilement localisable jusqu'au dernier programme intégré.
[Link] 6: Exploitation
Cette phase permet aussi de constater que l'application réalisée correspond bien aux spécifications
définies dans le cahier des charges. Elle doit fournir la preuve que l'application développée (logiciel
ou système) atteint bien tous les objectifs fixés dans le cahier des charges.
Toutefois il faut remarquer que cette preuve ne pourra être apportée qu'après un certain temps
d'utilisation.
2. ALGORITHMES.
2.1.Définition.
Certains voient, à tort, dans l'ordinateur une machine pensante et intelligente, capable de
résoudre bien des problèmes. En fait l’ordinateur est stupide mais très rapide, et ne serait
capable de rien si quelqu'un (le programmeur en l'occurence) ne lui avait fourni la liste des
actions à exécuter. Cette description doit être faite de manière non ambigüe car il ne faut pas
s'attendre à la moindre interprétation des ordres fournis. Ils seront exécutés de manière
purement mécanique.
De plus, les opérations élémentaires que peut exécuter un ordinateur sont en nombre restreint
et doivent être communiquées de façon précise dans un langage qu'il comprendra. Le
problème principal de l'utilisateur est donc de lui décrire la suite des actions élémentaires
permettant d'obtenir, à partir des données fournies, les résultats escomptés. Cette description
doit être précise, envisager le moindre détail et prévoir les diverses possibilités de données.
Cette marche à suivre porte le nom d'algorithme dont l'Encyclopaedia Universalis donne la
définition suivante:
" Un algorithme est une suite finie de règles à appliquer dans un ordre déterminé à un
nombre fini de données pour arriver, en un nombre fini d'étapes, à un certain résultat, et cela
indépendamment des données. "
4
Le mot algorithme provient du nom d'un célèbre mathématicien arabe de la première moitié
du IXe siècle: Muhammad ibn Musa al Khwarizmi.
Né vers 780 à Bagdad et mort vers 850. Il fut un de premier à trouver l’algorithme d'équation
de second degré et commença par écrire des faits mathématiques logiques et nouveaux, qui
furent soit admirés, soit critiqués et arrangés.
Le rôle de l'algorithme est fondamental. En effet, sans algorithme, il n'y aurait pas de
programme (qui n'est jamais que sa traduction dans un langage compréhensible par
l'ordinateur). De plus, les algorithmes sont fondamentaux en un autre sens: ils sont
indépendants à la fois de l'ordinateur qui les exécute, des langages dans lequel ils sont
énoncés et traduits.
Calcul de l'intérêt et de la valeur acquise par une somme placée pendant un an à intérêt
simple.
les données fournies: deux nombres représentant les valeurs de la somme placée et du taux
d'intérêt. les résultats désirés: deux nombres représentant l'intérêt fourni par la somme placée
ainsi que la valeur obtenue après placement d'un an. Il nous faut maintenant décrire les
différentes étapes permettant de passer des donnés aux résultats. Nos connaissances
générales nous permettent d'exprimer cette règle:
"Pour obtenir l'intérêt fourni par la somme, il suffit de multiplier la somme par le taux
d'intérêt divisé par cent; la valeur acquise s'obtient en additionnant ce dernier montant et la
somme initiale."
2.3.Méthodologie
Dans cet exemple simple apparaissent les trois étapes qui caractérisent la résolution d'un
problème sur ordinateur:
préciser les résultats que l'on désire obtenir ("sorties" ou "output" en anglais)
Le but final d'une méthodologie de programmation est de rédiger un programme particulier dans
un langage de programmation précis pour un type d'ordinateur. Mais il se trouve que cette
démarche devienne étroitement liée à l'informatique est en fait un cas particulier d'une
méthodologie générale : celle de description d'un algorithme.
Ces trois étapes ne sont pas indépendantes et leur ordre peut être modifié.
5
Si les résultats fournis par l'ordinateur ne sont pas corrects, c'est qu'une erreur s'est glissée soit
dans l'analyse du problème, soit dans la mise au point de l'algorithme, soit dans sa traduction
en langage de programmation car l'ordinateur ne fait qu'exécuter scrupuleusement les
opérations demandées.
[Link] de l’algorithme
Il est évident, même sur cet exemple simple, qu'une telle formalisation risque de produire un
texte long, difficile à comprendre et ne mettant pas clairement en évidence les différentes
étapes du traitement.
[Link] de description
Dans un langage de description, les actions sont généralement décrites par un symbole ou un
verbe à l'infinitif choisi pour éviter les confusions. Ce langage est appelé soit pseudocode soit
langage de description d'algorithme (LDA).
Ces verbes sont soulignés pour indiquer qu'ils ont un sens particulier, qu'il est interdit de les
utiliser dans un autre sens et qu'il seront traduits pour être rendus compréhensibles par la
machine.
Les valeurs manipulées dans cet algorithme sont des constantes (100) et des variables
(somme_initiale, taux, intérêt, valeur_acquise). Il est pratique de choisir le nom des variables
de manière à rappeler la signification de la valeur qu'elles représentent.
Ce nom est souvent appelé identificateur de la variable. Les variables jouent le rôle de
"tiroirs" dans lesquels on place une valeur durant l'exécution de l'algorithme.
6
Ainsi, lire somme_initiale signifie que l'on introduit dans le tiroir baptisé somme_initiale la
valeur numérique entrée au clavier lors de l'exécution du programme.
Le contenu d'un de ces tiroirs peut être modifié en y plaçant le résultat d'un calcul. Cette
instruction porte le nom d'assignation ou affectation et se représente par une flèche (<--).
Ainsi,
intérêt <-- somme_initiale * taux /100 : signifie que l'on place dans le tiroir intérêt le résultat
de l'opération figurant à droite de la flèche. Cette instruction se lit: assigner à la variable
intérêt la valeur de l'expression de droite.
Les expressions symbolisant les calculs à effectuer sont représentées par des formules
algébriques faisant intervenir les noms des variables, des symboles mathématiques ("+" pour
l'addition, "-" pour la soustraction, "*" pour la multiplication, "/" pour la division, ...) et des
constantes numériques.
La description d'une action et des objets qui y participent porte le nom d'instruction. L'ordre
dans lequel les différentes opérations seront écrites indique l'ordre dans lequel elles seront
exécutées: de haut en bas et de droite à gauche. Il s'agit d'une exécution séquentielle.
[Link] : Addition
1. écrire les deux nombres l'un en dessous de l'autre bien alignés
2. tirer un trait sous le deuxième le nombre
3. écrire dans la colonne unité sous le trait le nombre d'unités de la somme
4. écrire dans la colonne des dizaines au dessus du premier chiffre, la retenue c'est à
dire le nombre de dizaines de la somme (1 ou 0)
5. ajouter les chiffres des dizaines de la retenue
6. écrire dans la colonne des dizaines sous le trait du nombre de dizaines de la
somme
7. écrire dans la colonne centaine sous le trait la retenue, c'est à dire le nombre des
centaines de la somme
[Link] : Robot
Imaginons un robot domestique à qui nous devons fournir un algorithme lui permettant de
préparer une tasse de café soluble. Une première version de l'algorithme pourrait être:
Les étapes de cet algorithme ne sont probablement pas assez détaillées pour que le robot
puisse les interpréter.
Chaque étape doit donc être affinée en une suite d'étapes plus élémentaires, chacune étant
spécifiée d'une manière plus détaillée que dans la première version. Ainsi l'étape
7
1. faire bouillir l'eau peut être affinée en
1.1. Remplir la bouilloire d'eau
1.2. Brancher la bouilloire sur le secteur
1.3. Attendre l'ébullition
1.4. Débrancher la bouilloire
De même,
Certaines étapes étant encore trop complexes et sans doute incompréhensibles pour notre
robot, il faut les affiner davantage. Ainsi l'étape
Quand il procède à des affinements des différentes étapes, le concepteur d'un algorithme doit
naturellement savoir où s'arrêter. Autrement dit, il doit savoir quand une étape constitue une
primitive adéquate au point de ne pas avoir besoin d'affinement supplémentaire. Cela signifie
évidemment qu'il doit connaître quelle sorte d'étape le processeur peut interpréter. Par
exemple, le concepteur de l'algorithme précédent doit savoir que le robot peut interpréter
"brancher la bouilloire" ce qui de ce fait n'exige pas d'affinement, mais qu'en revanche, il ne
peut pas interpréter "remplir la bouilloire" et que dès lors un affinement devient nécessaire.
8
3. LA SEQUENCE.
[Link].
Dans les algorithmes décrivant des calculs sur les quantités numériques, seront utilisées
essentiellement les instructions que nous avons déjà étudiées.
lire variables
indiquant la saisie des données
exemples:
lire somme_initiale
lire taux
écrire expression
exemple:
[Link]
Exprimer un nombre de secondes sous forme d'heures, minutes, secondes. La seule donnée est
le nombre total de secondes que nous appellerons nsec; les résultats consistent en 3 nombres
h, m, s.
9
3.6.Déclaratives
Il est aussi nécessaire de préciser ce que les variables utilisées contiendront comme type de
données. Il peut s'agir de nombres entiers, de nombres réels, de chaînes de caractères, ... Il
faut faire précéder la description de l'algorithme par une partie dite déclarative où l'on
regroupe les caractéristiques des variables manipulées.
La partie déclarative est placée en tête de l'algorithme et regroupe une ou plusieurs indications
de la forme:
entier nsec, h, m, s
écrire "Introduisez le nombre de secondes:"
lire nsec
s <-- nsec mod 60
m <-- (nsec \ 60) mod 60
h <-- nsec \ 3600
écrire nsec, "valent: ", h, "heure(s)", m, "minute(s) et", s,
"seconde(s)"
Exemple 1: Chercher dans une liste de noms et d'adresses, l'adresse d'une personne à partir
de son nom. Le nombre de fois qu'il faudra comparer le nom donné aux noms de la liste est
dans ce cas inconnu.
10
Résolvons l'exemple 1:
...
lire nom_donné
lire nom1
si nom1 = nom_donné alors écrire adresse1
sinon lire nom2
si nom2 = nom_donné alors écrire adresse2
sinon lire nom3
si nom3 = nom_donné alors ...
…..
L'inconvénient de cet algorithme (en dehors de l'empiètement inévitable sur la marge de
droite) tient au fait que l'auteur ne sait pas quand il doit s'arrêter d'écrire. Plus précisément, il
lui est impossible de savoir combien de fois il doit écrire l'instruction de comparaison au
nom_donné.
Un problème identique surgit dans l'écriture d'un algorithme qui décrit comment calculer le
premier nombre premier qui soit plus grand qu'un nombre entier positif donné N.
lire N
i <-- N+1
si i est premier alors écrire i
sinon i <-- i+1
si i est premier alors écrire i
sinon i <-- i+1
si i est premier alors écrire i
sinon i <-- i+1
si ...
Le test "si i est premier alors" ne sera exécuté qu'une fois si N=4, il le sera quatre fois si
N=13, mais combien de fois faudra-t-il réécrire le test si N=7394485?
Ces exemples montrent que la séquence et l'alternative ne sont pas en elles-mêmes suffisantes
pour exprimer des algorithmes dont la longueur peut varier selon les circonstances. Il est donc
nécessaire d'introduire le moyen de répéter certaines instructions d'un algorithme un nombre
quelconque de fois. La structure qui permet cela est appelée structure répétitive.
lire nom_donné
i <-- 1
lire nomi
tant que NOT ((nomi = nom_donné) ou (fin de liste)) faire
i <-- i+1
lire nomi
fin tant
si nomi = nom_donné alors écrire adressei
sinon écrire "Le nom demandé ne se trouve pas dans la liste."
Fin si
lire N
11
i <-- N+1
tant que NOT (i est premier) faire
i <-- i+1
ftant
écrire i
Notons qu'il faudra exprimer autrement les conditions " (fin de liste) " et " (i est premier) ",
ces formes n'étant pas compréhensibles par les compilateurs/interpréteurs.
Considérons aussi l'exemple suivant: étant donnés deux nombres entiers m et n positifs ou
nuls, on demande d'en calculer le PGCD. L'algorithme d'Euclide permet de résoudre ce
problème en prenant d'abord le reste de la division de m par n, puis le reste de la division de n
par ce premier reste, etc jusqu'à ce qu'on trouve un reste nul. Le dernier diviseur utilisé est le
Remarquons que par définition, si un des nombres est nul, l'autre nombre est le PGCD .
Si nous avions pris m=140 et n=1386, nous aurions obtenu la suite de calculs suivants:
Dans cet exemple, nous devons répéter le calcul du reste de la division d'un nombre par un
autre. Pour fixer les idées, appelons a le dividende, b le diviseur et r le reste. Le calcul du reste
de la division de a par b se fait simplement au moyen de l'instruction :
r <-- a mod b
PGCD <-- a
écrire "Le PGCD de",m,"et",n,"est",PGCD
12
4.4. Commentaires
1) Les mots faire et ftant (abréviation de "fin de tant que") encadrent les instructions qui
doivent être exécutées plusieurs fois. On indique entre tant que et faire les conditions dans
lesquelles on doit exécuter le corps de la boucle.
En premier lieu, l'expression logique est évaluée (il faut donc veiller à sa valeur lors de
l'entrée dans la boucle): si sa valeur est vrai, le corps de la boucle est exécuté puis
l'expression logique est réévaluée (il faut donc qu'elle puisse changer de valeur pour sortir de
la boucle) et si elle a la valeur faux, on exécute l'instruction qui suit ftant.
3) Il est à noter qu'il est préférable d'exprimer l'expression logique sous la forme NOT
(condition(s) d'arrêt). Il est en effet plus simple de déterminer les raisons d'arrêter le
processus répétitif que celles de continuer.
entier N, i
réel x, puiss
lire N, x
puiss <-- 1
i <-- 1
tant que NOT(i > N) faire
puiss <-- puiss * x
i <-- i + 1
ftant
écrire "La puissance",N,"ème de",x,"est",puiss
Cependant, le nombre d' exécutions du corps de la boucle étant connu à l'avance, une boucle
"pour" est d'un emploi plus simple:
entier N, i
réel x, puiss
lire N, x
puiss <-- 1
pour i de 1 à N faire
puiss <-- puiss * x
fpour
écrire "La puissance",N,"ème de",x,"est",puiss
13
4.6. Commentaires
1° Les mots faire et fpour (abréviation de "fin du pour") encadrent les instructions qui
doivent être exécutées plusieurs fois. On précise entre pour et faire comment seront
contrôlées les répétitions. On y définit une variable appelée variable de contrôle (i dans
l'exemple) et les valeurs que prendra cette variable: une première valeur ou valeur initiale
indiquée après le mot de, une dernière valeur ou valeur finale indiquée après le mot à. La
variable de contrôle est initialisée à la première valeur. Avant chaque exécution du corps
de la boucle, la valeur de la variable de contrôle est comparée à la valeur finale. Si la
variable de contrôle ne dépasse pas cette valeur, on exécute le corps de la boucle, sinon on
passe à l'instruction qui suit le mot fpour. Après chaque exécution du corps de la boucle,
la variable de contrôle est augmentée d'une unité.
3° Il est parfois utile de faire varier la variable de contrôle par valeurs décroissantes, ou
par incréments différents de l'unité. Dans ce cas, il faut utiliser la forme la plus générale
de la boucle "pour":
où
v.c. est le nom de la variable de contrôle
[Link]. est la première valeur (ou valeur initiale)
[Link]. est la dernière valeur (ou valeur finale)
incr. est l'incrément, c'est-à-dire la quantité non nulle ajoutée à la variable de
contrôle à la fin de chaque exécution du corps de la boucle.
Il est important de noter ici l'impossibilité de traduire en Pascal les boucles avec des
incréments différents de 1 et -1.
14
4° La première valeur, la dernière valeur et l'incrément peuvent être des expressions
numériques. Les instructions du corps de la boucle ne peuvent en aucun cas modifier ces
valeurs.
5° En fin de boucle, la valeur de la variable de contrôle n'est pas toujours égale à la valeur
finale (à vérifier avec votre compilateur). Il est donc dangereux d'utiliser celle-ci.
Comme la boucle "tant que", ce type de répétitive est utilisé lorsque le nombre de fois que la
séquence d'instructions à répéter est inconnu au moment où cette séquence est abordée pour la
premiè fois mais le corps de la boucle est toujours exécuté au moins une fois.
Sa formulation générale est:
répéter
séquence d'instructions
jusqu'à (expression logique)
L'expression logique est évaluée aprés l'exécution du corps de la boucle: si sa valeur est faux,
le corps de la boucle est exécuté à nouveau puis l'expression logique est réévaluée (il faut
donc qu'elle puisse changer de valeur pour sortir de la boucle) et si elle a la valeur vrai, on
exécute l'instruction qui suit jusqu'à. Attention, si ceci correspond tout à fait à l'usage
familier que nous faisons de l'expression répéter ... jusqu'à, le test effectué est la négation de
celui utilisé dans la boucle "tant que" et ceci peut parfois prêter à confusion.
Il faut en effet remarquer que dans
[Link].
15
3- L'ordinateur "choisit" un nombre entier compris entre 0 et 100. Un joueur essaie de le
deviner. Lors de chaque essai, l'ordinateur affiche la "fourchette" dans laquelle se trouve le
nombre qu'il a choisi.
Supposons que l'on veuille demander à l'utilisateur de choisir dans un menu une des 3
possibilités offertes. Le choix présenté ne se limite pas à une alternative (soit - soit).
Nous nous trouvons en présence d'un choix multiple qui s'écrit en LDA:
entier i
lire i
selon que
i=1 : instruction 1
i=2 : instruction 2
i=3 : instruction 3
autrement écrire "Mauvais choix"
fselon
La première forme généralise le si ... alors ... sinon ... fsi, la seconde le si ... alors ... fsi.
Si la i ème expression logique a la valeur vrai, la i ème séquence d'instructions est exécutée
puis il y a passage aux instructions qui suivent le mot fselon. Si toutes les expressions
logiques ont la valeur faux, on exécute dans le premier cas la séquence d'instructions qui suit
le mot autrement , dans le deuxième cas on passe directement à ce qui suit fselon.
Afin d'éviter toute ambiguïté, on exige que les différentes expressions logiques soient
mutuellement exclusives.
4.10. Exercices.
5. LES TABLEAUX
[Link] de tableau
16
Les tableaux servent à désigner une suite finie d'éléments de même type au moyen d'une
unique variable. Ces éléments peuvent être des entiers, des chaînes, ... Ils sont stockés dans les
différentes cases du tableau, habituellement numérotées de 0 à n-1, n représentant la taille du
tableau (le nombre de cases dans le tableau).
Le type d'un tableau précise l'intervalle de définition et le type (commun) des éléments.
tableau type_des_éléments[borne_inférieure .. borne_supérieure]
En général, nous choisirons toujours la valeur 0 pour la borne inférieure dans le but de
faciliter la traduction de l'algorithme vers les autres langages (C, Java, ...). Par exemple, pour
un tableau de 10 entiers, on pourra écrire :
t : tableau entier[0..9]
Pour accéder à un élément du tableau, il suffit de préciser entre crochets l'indice de la case
contenant cet élément. Par exemple, pour accéder au septième élément (49) du tableau
d'entiers ci-dessus, on écrit : t[6]. L'instruction suivante affecte à la variable x la valeur du
premier élément du tableau, c'est à dire 45 :
x <- t[0]
L'élément désigné du tableau peut être utilisé comme n'importe quelle variable : t[6] <- 43
0 1 2 3 4 5 6 7 8 9
45 54 1 -56 22 134 43 12 90 -27
La plupart des algorithmes basés sur les tableaux utilisent des itérations permettant de faire un
parcours complet ou partiel des différents éléments du tableau. De tels algorithmes établissent
le résultat recherché par récurrence en fonction des éléments successivement rencontrés.
[Link]
17
procedure écrireTableau(n : entier, tab : tableau entier[0..n-1])
début
pour i de 0 à n-1 faire
écrire(tab[i])
fpour
fin
Algorithme
début Lexique :
n <- lire() - n : entier, taille du tableau
Pour i de 0 à n-1 faire - tab : tableau entier[0..n-1]
tab[i] <- lire()
fpour
écrireTableau(n, tab) // appel de la procédure
fin
Exemple 2
[Link]
On cherche ici à savoir si un tableau saisi au clavier n'est constitué que d'entiers positifs :
18
Algorithme
début
tab <- lire()
i <- 0
positif <- vrai
tant que positif et i < n faire Lexique :
si tab[i] < 0 - i : entier, indice d'itération
alors positif <- faux - n : entier, taille du tableau
- tab : tableau entier[O..n-1]
fsi - positif : booléen, vrai si aucun entier
i <- i+1 négatif n'a été détecté
ftant
si positif
alors écrire("tableau d'entiers naturels")
sinon écrire("tableau d'entiers relatifs")
fsi
fin
[Link] imbriqués
Certains algorithmes sur les tableaux font appel à des boucles imbriquées : la boucle
principale sert généralement à parcourir les cases une à une, tandis que le traitement de
chaque case dépend du parcours simple d'une partie du tableau (par exemple toutes les cases
restantes), ce qui correspond à la boucle interne.
[Link]
La fonction suivante calcule, pour chaque case d'un tableau, le nombre de cases suivantes qui
contiennent un élément strictement supérieur. Les résultats sont placés dans un tableau.
[Link] multidimensionnels
19
Les cases d'un tableau à une dimension sont indicées de manière consécutive (cases
"alignées"). Il est possible de disposer ces cases selon des grilles (tableaux à deux
dimensions), des cubes (tableaux à trois dimensions),
Les algorithmes les plus simples sur ces tableaux utilisent néanmoins en général des boucles
imbriquées : chaque niveau de boucle correspond au parcours selon une dimension.
Ces tableaux sont faciles à se représenter comme une grille (ou matrice) ayant un certain
nombre de lignes (première dimension) et un certain nombre de colonnes (seconde
dimension).
Un tel tableau, avec 5 colonnes et 3 lignes, peut par exemple contenir les éléments suivants :
0 1 2 3 4
0 45 54 1 -56 22
1 64 8 54 34 2
2 56 23 -47 0 12
Pour accéder à un élément du tableau, il suffit de préciser entre crochets l'indice de la case
contenant cet élément, et ce pour chacune des dimensions. Par exemple, pour accéder à
l'élément 23 du tableau d'entiers ci-dessus, on écrit : t[2,1]. L'instruction suivante affecte à la
variable x la valeur du premier élément du tableau, c'est à dire 45.
x <- t[0,0]
L'élément désigné du tableau peut alors être utilisé comme n'importe quelle variable :
t[2,1] <- 43
Cette instruction a modifié le tableau :
0 1 2 3 4
0 45 54 1 -56 22
1 64 8 54 34 2
2 56 43 -47 0 12
20
fonction somme(li:entier,co:entier,t:tableau entier[0..li-1, 0..co-1]):entier
début
s <- 0
Pour i de 0 à li-1 faire
Lexique :
Pour j de 0 à co-1 faire - li : entier, nombre de lignes du tableau
s <- s + t[i,j] - co : entier, nombre de colonnes du tableau
fpour - t : tableau entier[0..li-1, 0..co-1], tableau dont on cherche
fpour l'élément maximal
- s : entier, somme des éléments déjà parcourus
- i : entier, indice d'itération sur les lignes
retourne s - j : entier, indice d'itération sur les colonnes
fin
On compare l'élément cherché à celui qui se trouve au milieu du tableau. Si l'élément cherché
est plus petit, on continue la recherche dans la première moitié du tableau sinon dans la
seconde. On recommence ce processus sur la moitié. On s'arrête lorsqu'on a trouvé ou lorsque
l'intervalle de recherche est nul.
5.11. Exemple
Exemple de recherche dans le tableau d'entiers suivant défini sur l'intervalle [3..10] :
5 13 18 23 46 53 89 97
3 4 5 6 7 8 9 10
Recherche de 46 :
Etape 1 : comparaison de 46 avec t[6] (6=(10+3)÷2), t[6]<46 => recherche dans [7..10]
Etape 2 : comparaison de 46 avec t[8], t[8]>46 => recherche dans [7..7]
Etape 3 : comparaison de 46 avec t[7], t[7]=46 => élément cherché trouvé à l'indice 7
Recherche de 10 :
21
Ce qui suit est incontournable. Combien de fois au cours d’une carrière (brillante) de
développeur a-t-on besoin de ranger des valeurs dans un ordre donné ? C’est incalculable.
Aussi, plutôt qu’avoir à réinventer à chaque fois la roue, le fusil à tirer dans les coins, le fil à
couper le roquefort et la poudre à maquiller, vaut-il mieux avoir assimiler quelques techniques
solidement éprouvées, même si elles paraissent un peu ardues au départ.
Il existe plusieurs stratégies possibles pour trier les éléments d’un tableau ; nous en verrons
une : le tri par sélection.
Admettons que le but de la manœuvre soit de trier un tableau de 12 éléments dans l’ordre
croissant.
45 122 12 3 21 78 64 53 89 28 84 46
3 122 12 45 21 78 64 53 89 28 84 46
On recommence à rechercher le plus petit élément, mais cette fois à partir du deuxième
élément. On le trouve en 3e position, on échange donc le deuxième avec le troisième :
3 12 122 45 21 78 64 53 89 28 84 46
3 12 21 45 122 78 64 53 89 28 84 46
Pour i 1 à 11
mini = t(i)
posmini = i
Pour j i + 1 à 12
Si t(j) < mini alors
mini t(j)
posmini j
Finsi
j suivant
t(posmini) t(i)
t(i) mini
i suivant
22
début
debut <- 0
fin <- n-1
trouve <- faux
tant que debut <= fin et non trouve faire
i <- (debut+fin)÷2
si t[i] = e
alors trouve <- vrai
sinon si t[i] > e Lexique :
alors fin <- i-1 - e : entier, élément recherché
sinon debut <- i+1 - n : entier, taille du tableau
- t : tableau entier[0..n-1], tableau trié par ordre croissant
fsi - debut : entier, début de la zone de recherche
fsi - fin : entier, fin de la zone de recherche
ftant - trouve : booléen, faux tant que l'élément cherché n'est pas trouvé
- i : entier, indice de la case du milieu de la zone de recherche
si trouve - indice : entier, indice de l'élément recherché ou -1 s'il n'est pas trouvé
alors indice <- i
sinon indice <- -1
fsi
retourne indice
fin
5.13. Exercices.
1. Etant donné un vecteur de nombres triés par ordre croissant, chercher si un nombre donné x
figure parmi les composantes. Si oui, indiquer la valeur de l'indice correspondant.
2. Bonhomme pendu. L'algorithme lit un mot proposé par un premier joueur. L'algorithme
affiche ensuite le mot où toutes les lettres sauf la première et la dernière sont remplacées par
un tiret. Un deuxième joueur propose des lettres une à une. Chaque fois que la lettre se trouve
dans le mot, l'algorithme remplace les tirets qui remplaçaient cette lettre et réaffiche le mot.
Le second joueur a droit à un maximum de 6 essais infructueux (lettre ne se trouvant pas dans
le mot).
3. Carrés magiques d'ordre impair. Un carré magique d'ordre n est un tableau carré à n lignes
et n colonnes, donc de n² cases, dans lesquelles on écrit une et une seule fois les nombres
entiers de 1 à n², de telle sorte que la somme des n nombres de chaque ligne, de chaque
colonne et de chaque diagonale soit toujours la même. On dispose pour les carrés magiques
d'ordre impair de l'algorithme suivant:
(b) ayant placé le nombre k dans la case (i,j) on place le nombre k+1 dans la case (i+1,j+1),
toutefois si cette case est occupée on place le nombre k+1 dans la case (i-1,j).
Lorsque les indices calculés sont supérieurs à n, on prend 1 comme indice. Ces opérations se
font pour 1<=k<=n²-1.
4. Jeu de Marienbad. On place des allumettes sur 4 rangées: 1 allumette sur la première,
sur la seconde, 5 sur la troisième et 7 sur la dernière. Deux joueurs peuvent
23
alternativement ôter, sur une seule rangée à la fois, autant d'allumettes qu'ils le
souhaitent mais au moins une. Le joueur qui enlève la dernière allumette a perdu.
5. Lire un texte d'au moins 120 caractères. Compter et afficher le nombre d'occurences
(d'apparition) de chacune des lettres de l'alphabet.
6. Nous désignerons par a1, a2, ..., an les éléments d'un tableau à trier par ordre croissant.
On commence par chercher l'indice du plus petit des éléments, soit j cet indice. On
permute alors les valeurs de a 1 et aj .On cherche ensuite l'indice du plus petit des
éléments a2, a3, ..., an et on permute avec a2, etc.
5.14. Exercices.
1. Calculer la racine carrée de a grâce à la formule récurrente x = 1/2 (x + a/x). Les calculs
commenceront avec 1 comme valeur initiale de x et stopperont quand la valeur absolue de
la différence entre les deux dernières valeurs calculées sera inférieure à 10 -6.
4. Lire un nombre entier, la base dans lequel il est exprimé et celle dans lequel il doit être
exprimé. Effectuer la conversion et afficher le résultat.
5. Lire une chaîne de caractères et la mettre en majuscules.
8. Lire deux nombres entiers N1 et N2. Si un des nombres est nul, l'autre est le PGCD sinon
il faut soustraitre le plus petit du plus grand et laisser le plus petit inchangé. Puis,
recommencer ainsi avec la nouvelle paire jusqu'à ce que un des deux nombres soit nul.
Dans ce cas, l'autre nombre est le PGCD
11. Rédigez en LDA (langage de description d’algorithme) un algorothme qui réalise le jeu suivant :
(a) A tour de rôle, l'ordinateur et le joueur choisissent un nombre qui ne peut prendre que 3
valeurs: 0, 1 ou 2.
Note: l'instruction
N <-- Random(3)
réalise le choix de l'ordinateur. (voir l’instruction case )
24
(b) Si la différence entre les nombres choisis vaut 2, le joueur qui a proposé le plus grand
nombre gagne un point 1, le joueur qui a proposé le plus petit nombre gagne un point
0, aucun point n'est marqué.
(c) Le jeu se termine quand un des deux joueurs (l'ordinateur ou le joueur humain) totalise 10
points ou quand l'être humain introduit un nombre négatif qui indique sa volonté d'arrêter de
jouer.
25
Ecrire un algorithme qui déclare et remplisse un tableau de 7
valeurs numériques en les mettant toutes à zéro.
Exercice 6.2
Ecrire un algorithme qui déclare et remplisse un tableau
contenant les six voyelles de l’alphabet latin.
Exercice 6.3
Ecrire un algorithme qui déclare un tableau de 9 notes, dont
on fait ensuite saisir les valeurs par l’utilisateur.
Exercice 6.4
Que produit l’algorithme suivant ?
Début
Pour i ← 0 à 5
Nb(i) ← i * i
i Suivant
Pour i ← 0 à 5
Ecrire Nb(i)
i Suivant
Fin
Exercice 6.5
Que produit l’algorithme suivant ?
Pour i ← 0 à 6
Ecrire N(i)
i Suivant
Fin
Exercice 6.6
Que produit l’algorithme suivant ?
26
Tableau Suite(7) en Entier
Variable i en Entier
Début
Suite(0) ← 1
Suite(1) ← 1
Pour i ← 2 à 7
Suite(i) ← Suite(i-1) + Suite(i-2)
i suivant
Pour i ← 0 à 7
Ecrire Suite(i)
i suivant
Fin
Exercice 6.7
Ecrivez la fin de l’algorithme 6.3 afin que le calcul de la
moyenne des notes soit effectué et affiché à l’écran.
Exercice 6.8
Ecrivez un algorithme permettant à l’utilisateur de saisir un
nombre quelconque de valeurs, qui devront être stockées dans un
tableau. L’utilisateur doit donc commencer par entrer le nombre
de valeurs qu’il compte saisir. Il effectuera ensuite cette
saisie. Enfin, une fois la saisie terminée, le programme
affichera le nombre de valeurs négatives et le nombre de
valeurs positives.
Exercice 6.9
Ecrivez un algorithme calculant la somme des valeurs d’un
tableau (on suppose que le tableau a été préalablement saisi).
Exercice 6.10
Ecrivez un algorithme constituant un tableau, à partir de deux
tableaux de même longueur préalablement saisis. Le nouveau
tableau sera la somme des éléments des deux tableaux de départ.
Exemple :
Tableau 1 : 4 – 8 – 7 – 9 – 1 – 5 – 4 – 6
Tableau 2 : 7 – 6 – 5 – 2 – 1 – 3 – 7 – 4
Tableau à constituer : 11 – 14 – 12 – 11 – 2 – 8 – 11 - 10
Exercice 6.11
Toujours à partir de deux tableaux précédemment saisis, écrivez
un algorithme qui calcule le schtroumpf des deux tableaux. Pour
calculer le schtroumpf, il faut multiplier chaque élément du
tableau 1 par chaque élément du tableau 2, et additionner le
tout.
Exemple :
27
Tableau 1 : 4 – 8 – 7 - 12
Tableau 2 : 3 – 6
Le Schtroumpf :
Exercice 6.12
Ecrivez un algorithme qui permette la saisie d’un nombre
quelconque de valeurs, sur le principe de l’ex 6.8. Toutes les
valeurs doivent être ensuite augmentées de 1, et le nouveau
tableau sera affiché à l’écran.
Exercice 6.13
Ecrivez un algorithme permettant, toujours sur le même
principe, à l’utilisateur de saisir un nombre déterminé de
valeurs. Le programme, une fois la saisie terminée, renvoie la
plus grande valeur en précisant quelle position elle occupe
dans le tableau. On prendra soin d’effectuer la saisie dans un
premier temps, et la recherche de la plus grande valeur du
tableau dans un second temps.
Exercice 6.14
Toujours et encore sur le même principe, écrivez un algorithme
permettant, à l’utilisateur de saisir les notes d'une classe.
Le programme, une fois la saisie terminée, renvoie le nombre de
ces notes supérieures à la moyenne de la classe.
Exercice 6.14
Avec les éléments vus dans cette première partie, voici
quelques exercices simples à réaliser:
28
Exercice 6.1
Tableau Truc(6) en Entier
Variable i en Entier
Debut
Pour i ← 0 à 6
Truc(i) ← 0
i Suivant
Fin
Exercice 6.2
Tableau Truc(5) en Caractère
Debut
Truc(0) ← ”a“
Truc(1) ← ”e“
Truc(2) ← ”i“
Truc(3) ← ”o“
Truc(4) ← ”u“
Truc(5) ← ”y“
Fin
Exercice 6.3
Tableau Notes(8) en Entier
Variable i en Entier
Début
Pour i ← 0 à 8
Ecrire "Entrez la note numéro ", i + 1
Lire Notes(i)
i Suivant
Fin
Exercice 6.4
Cet algorithme remplit un tableau avec six valeurs : 0, 1, 4,
9, 16, 25. Il les écrit ensuite à l’écran. Simplification :
Variable i en Entier
Début
Pour i ← 0 à 5
Nb(i) ← i * i
Ecrire Nb(i)
i Suivant
Fin
Exercice 6.5 :
Cet algorithme remplit un tableau avec les sept valeurs : 1, 3, 5, 7, 9, 11,
13. Il les affiche ensuite :
29
Tableau N(6) en Entier
Variables i, k en Entier
Début
N(0) ← 1
Ecrire N(0)
Pour k ← 1 à 6
N(k) ← N(k-1) + 2
Ecrire N(k)
k Suivant
Fin
Exercice 6.6
Cet algorithme remplit un tableau de 8 valeurs : 1, 1, 2, 3, 5, 8, 13, 21
Exercice 6.7
Variable S en Entier
Tableau Notes(8) en Entier
Debut
s ← 0
Pour i ← 0 à 8
Ecrire “Entrez la note n° “, i + 1
Lire Notes(i)
s ← s + Notes(i)
i Suivant
Ecrire “Moyenne : “, s/9
Fin
Exercice 6.8
Variables Nb, Nbpos, Nbneg en Entier
Tableau T() en Entier
Debut
Ecrire “Entrez le nombre de valeurs :“
Lire Nb
Redim T(Nb - 1)
Nbpos ← 0
Nbneg ← 0
Pour i ← 0 à Nb – 1
Ecrire “Entrez le nombre n° “, i + 1
Lire T(i)
Si T(i) > 0 alors
Nbpos ← Nbpos + 1
Sinon
Nbneg ← Nbneg + 1
Finsi
i Suivant
Ecrire “Nombre de valeurs positives : “, Nbpos
Ecrire “Nombre de valeurs négatives : “, Nbneg
Fin
Exercice 6.9
30
Variables i, Som, N en EntierTableau T() en Entier
Debut
… (on ne programme pas la saisie du tableau, dont on suppose
qu’il compte N éléments)
Redim T(N - 1)
…
Som ← 0
Pour i ← 0 à N – 1
Som ← Som + T(i)
i Suivant
Exercice 6.10
Variables i, N en Entier
Tableaux T1(), T2(), T3() en Entier
Debut
… (on suppose que T1 et T2 comptent N éléments, et qu’ils sont
déjà saisis)
Redim T3(N - 1)
…
Pour i ← 0 à N – 1
T3(i) ← T1(i) + T2(i)
i Suivant
Fin
Exercice 6.11
Variables i, j, N1, N2, S en Entier
Tableaux T1(), T2() en Entier
Debut
… On ne programme pas la saisie des tableaux T1 et T2.
On suppose que T1 possède N1 éléments, et que T2 en possède T2)
…
S ← 0
Pour i ← 0 à N1 – 1
Pour j ← 0 à N2 – 1
S ← S + T1(i) * T2(j)
j Suivant
i Suivant
Fin
Exercice 6.12
31
Variables Nb, i en Entier
Tableau T() en Entier
Debut
Ecrire “Entrez le nombre de valeurs :“
Lire Nb
Redim T(Nb - 1)
Pour i ← 0 à Nb – 1
Ecrire “Entrez le nombre n° “, i + 1
Lire T(i)
i Suivant
Ecrire "Nouveau tableau :"
Pour i ← 0 à Nb – 1
T(i) ← T(i) + 1
Ecrire T(i)
i Suivant
Fin
Exercice 6.13
Posmaxi ← 0
Pour i ← 0 à Nb – 1
Si T(i) > T(Posmaxi) alors
Posmaxi ← i
Finsi
i Suivant
Exercice 6.14
32
Il n'y a pas de correction unique, celles qui sont proposées
ici représentent juste une manière de faire.
1) "Calculer le volume d'un pavé"
Similaire à l'exemple du calcul de la surface d'un carré.
On se contente de lire les valeurs, de faire le calcul et
d'afficher le résultat.
LIRE longueur
LIRE largeur
LIRE hauteur
volume = longueur x largeur x hauteur
ECRIRE volume
LIRE heure
LIRE minutes
LIRE secondes
total_secondes = (heure x 3600) + (minutes x 60) + secondes
ECRIRE total_secondes
Exercices corrigés
33
Exercice 1 : Lire 2 nombres a et b. Les écrire dans l'ordre croissant.
réel a, b
écrire "Introduisez a:"
lire a
écrire "Introduisez b:"
lire b
si a>b alors écrire b, a
sinon écrire a, b
fsi
Exercice 3 : Déterminer si l'année A est bissextile. Note: Si A n'est pas divisible par
4, l'année n'est pas bissextile. Si A est divisible par 4, l'année est bissextile sauf si A est
divisible par 100 et pas par 400.
entier A
écrire "Introduisez l'année:"
lire A
si NOT (A mod 4=0) alors écrire "L'année ", A, "n'est pas
bissextile."
sinon si NOT (A mod 100=0) alors écrire "L'année ", A, "est
bissextile."
sinon si NOT (A mod 400=0) alors écrire "L'année ", A, "n'est pas
bissextile."
sinon écrire "L'année ", A, "est bissextile."
fsi
fsi
fsi
34
entier A
écrire "Introduisez l'année:"
lire A
si (A mod 4=0) et ((A mod 100>0) ou (A mod 400=0)) alors
écrire "L'année ", A, "est bissextile."
sinon écrire "L'année ", A, "n'est pas bissextile."
fsi
Exercice 14: Déterminer la valeur absolue d'un nombre réel x à partir de la définition
de la valeur absolue.
réel x
écrire "Introduisez x:"
lire x
si x>0 alors écrire "Valeur absolue =", x
sinon si x=0 alors écrire "Valeur absolue =", 0
sinon écrire "Valeur absolue =", -x
fsi
fsi
35
sinon écrire "r=", r ," et t n'existe pas."
fsi
fsi
s <-- a \ 100
JD <-- 1720996,5 - s + s \ 4 + [365,25*a] + [30,6001*(M+1)] + j
JD <-- JD - [JD/7]*7
JS <-- [JD] mod 7
selon que
JS = 0 : Dat <-- "mardi";
JS = 1 : Dat <-- "mercredi";
JS = 2 : Dat <-- "jeudi";
JS = 3 : Dat <-- "vendredi";
JS = 4 : Dat <-- "samedi";
JS = 5 : Dat <-- "dimanche";
JS = 6 : Dat <-- "lundi";
fselon
36
Mettre +1 dans Sign
"Enlever" un nombre entier de tours grâce à:
- Rad = Rad - 2 * pi * [Rad / (2*pi)] si rad<0
- Rad = Rad + 2 * pi * [-Rad / (2*pi)] + 2*pi
si rad>=0
Si Rad>pi, le ramener entre 0 et pi en soustrayant pi et s'en
souvenir en
mettant -1 dans Sign
Si Rad>pi/2, faire Rad = pi - Rad
Si Rad>pi/4, * faire Rad = pi/2 - Rad
- Sinus vaut 1 - Rad*Rad/2 + Rad*Rad*Rad*Rad/24
Si Rad<=pi/4,
Sinus = Rad - Rad*Rad*Rad/6 +Rad*Rad*Rad*Rad*Rad/120
37
calculer les 2 entiers caractérisant l'heure de mi-marée. Il
calcule de plus avec des nombres réels la hauteur d'eau.
Algorithme CalculMiMaree
{ Calcule le temps et la hauteur de la mi-marée, en fonction
des temps et hauteurs des marées haute et basse. Pour calculer
le temps de la mi-marée convertit les temps en minutes pour
faire la moyenne, et convertit le resultat en heures et minutes
}
début
38
lire (HauteurHaut)
TempsBas <-- 60 * HBas + MnBas { conversion des
heures/minutes }
TempsHaut <-- 60 * HHaut + MnHaut { en nombre de minutes
depuis 0H00 }
HauteurMi <-- (HauteurBas + HauteurHaut)/2 { moyenne des
hauteurs }
TempsMi <-- (TempsBas + TempsHaut) div 2 { division
entière par 2 }
HMi <-- TempsMi div 60 { division
entière par 60 }
MnMi <-- TempsMi mod 60 { reste de la
division par 60 }
ecrire ('La mi-maree est a : ', HMi, 'H', MnMi)
ecrire ('avec la hauteur d eau : ', HauteurMi ,
'm')
fin
Exemple d'algorithme
debut
demander a l'utilisateur son revenu annuel
memoriser sa reponse sous le nom: revenu
demander a l'utilisateur son nombre de part
memoriser sa reponse sous le nom: nbparts
SI revenu/nbparts < 25460
ALORS afficher : Vous n'avez pas d'impots a payer
SINON afficher : Le montant de votre impot est:
(revenu*0,25)-(nbparts*5260)
fin
6. Fonctions et procédures
39
6.1.Définition
Une procédure représente un bloc d'instructions combinées, le cas échéant, avec des structures
de contrôle. une fois définie, elle peut être utilisée dans le programme comme si elle était
native du langage.
Exemple
Entrée Sortie
L'entête d'une fonction spécifie son nom, le type de son résultat, et les paramètres (avec leurs
types). Ces paramètres sont considérés comme les données transmises à la fonction, c'est à
dire l'entrée de la fonction. Il peut arriver que la fonction modifie ces paramètres lors de
l'exécution de son algorithme. On parle alors de paramètre modifiable : il s'agit à la fois d'une
entrée et d'une sortie de l'algorithme. La déclaration d'un tel paramètre dans la liste des
paramètres se fait de la manière suivante :
Exemple :
debut
entier M
M<-T(i)
T(i)<-T(j)
T(j)<-M
fin
Une fonction est basée sur le même principe qu'une procédure. Seulement la procédure ne se
contente que d'exécuter les instructions qui la composent alors que la fonction renvoie une
valeur : la procédure est utilisée comme une primitive alors que la fonction est utilisée par
affectation ou en paramètre d'un autre bloc.
(Les paramètres sont des variables qui permettent d'utiliser plusieurs fois les procédures et
fonctions avec des valeurs différentes.)
40
tri_bulle(tableau T) tri_bulle_optimise(tableau T)
debut debut
entier longueur, i entier longueur, i
booleen inversion booleen inversion
longueur<-taille(T) longueur<-taille(T)
faire faire
inversion=faux inversion<-faux
pour i=0 à (longueur-1) pour i=0 à (longueur-1)
si T(i)>T(i+1) si T(i)>T(i+1)
echanger(T,i,i+1) echanger(T,i,i+1)
inversion<-vrai inversion<-vrai
fin si fin si
fin pour longueur<-longueur-1
tantque inversion fin pour
fin tantque inversion
fin
41
7. Les structures de données
3.1 Motivation
Les structures de données vues jusqu'à présent sont statiques. Une variable correspond à un
espace mémoire défini et figé. De même pour un tableau : le nombre de cases est fixé une fois
pour toutes. Explication : le programme réserve de la mémoire lors de la déclaration de
variables; on ne sait pas ce qu'il y a dans la mémoire autour de l'espace réservé; on ne peut
donc pas augmenter l'espace réservé de façon contiguë.
D'où l'idée de faire des structures de données dynamiques. On se rend bien compte qu'on a
très souvent besoin de rajouter/enlever des données de façon dynamique (Carnet d'adresse,
liste de notes, etc...).
``Une liste chaînée est une structure de données dans laquelle les objets sont arrangés
linéairement. Toutefois, contrairement au tableau, pour lequel l'ordre linéaire est déterminé
par les indices, l'ordre d'une liste chaînée est déterminé par un pointeur dans chaque objet.''
[Link] exemple:
contenu(Liste) = 9
contenu(suivant(Liste) = 3
contenu(suivant(suivant(Liste)) = 5
contenu(suivant(suivant(suivant(Liste))) = 2
Liste est une variable (un espace mémoire) dans laquelle il y a un pointeur (une flèche) vers la
première cellule (premier maillon de la chaîne). Chaque cellule (ou maillon) est constitué,
dans notre exemple, de deux cases mémoire :
42
une case où il y une valeur entière appelée contenu
une case où il y a un pointeur appelée suivant
Pour chaîner les éléments, il faut mettre dans suivant le pointeur vers la cellule suivante.
On peut voir les listes chaînées un peu comme une course au trésor. Au début, on vous
indique où est le premier trésor (sous le chêne par exemple). Vous allez chercher le premier
élément (trésor) et avec il y a un papier qui vous dit où est le second élément (sous la
balançoire), et ainsi de suite...
Vous ne savez pas au début où sont les éléments. Vous devez accèder à un élément pour
savoir où trouver le suivant.
AFFICHER_LISTE(Liste)
curseur <- Liste
tant que (curseur <> NIL)
faire afficher(contenu(curseur))
curseur <- suivant(curseur)
Bien entendu, on peut mettre plusieurs informations dans chaque cellule de la liste chaînée,
c'est à dire qu'on peut faire des cellules ``plus grosses'' avec plus de cases mémoires. On
conservera tout de même la case suivant qui permet de chaîner les éléments (si on ne conserve
pas cette case, comment chaîner les éléments entre eux ???).
Dans cette cellule, il y a les cases téléphone, portable, bureau et anniversaire dans lesquelles
ont met des chiffres et les cases Nom, Prénom et Adresse dans lesquelles ont met du texte. La
case suivant est toujours une case contenant un pointeur.
En quoi une liste chaînée est dynamique ? On crée une cellule, et on l'accroche dans la liste en
mettant à jour les champs suivant.
43
Ecrire un algorithme Ajout_fin(cellule, liste) qui ajoute une cellule pointée par cellule à la fin
de la liste liste.
Ajout_fin(cellule, liste)
curseur <- liste
tant que (curseur <> NIL)
faire curseur <- suivant(curseur)
curseur <- cellule
Ajout_fin(cellule, liste)
si (liste = NIL)
alors
liste <- cellule
sinon
curseur <- liste
tant que (suivant(curseur) <> NIL)
faire curseur <- suivant(curseur)
suivant(curseur) <- cellule
ou alors avec une variable cellule_précédente
Ajout_fin(cellule, liste)
curseur <- liste
cellule_précédente <- NIL
tant que (curseur <> NIL)
faire cellule_précédente <- curseur
curseur <- suivant(curseur)
si (cellule_précédente = NIL)
alors
liste <- cellule
sinon
suivant(cellule_précédente) <- cellule
Ajout_début(cellule, liste)
si (liste = NIL)
alors
liste = cellule
sinon
suivant(cellule) <- liste
44
liste <- cellule
On suppose que la liste liste est triée dans l'ordre croissant. Ecrire un algorithme
Ajout_triée(cellule, liste) qui ajoute une cellule pointée par cellule à sa place dans la liste.
Comme énoncé précédemment, il faut gérer tous les cas de figures. Ici, il a 4 cas:
Ajout_triée(cellule, liste)
si liste <> NIL
alors
curseur <- liste
cellule_précédente <- NIL
tant que (curseur <> NIL) ET (contenu(curseur) < contenu(cellule))
faire cellule_précédente <- curseur
curseur <- cuivant(curseur)
si (cellule_précédente = NIL)
alors
liste <- cellule
suivant(cellule) <- curseur
sinon
suivant(cellule_précédente) <- cellule
suivant(cellule) <- curseur
sinon
liste <- cellule
45
faire cellule_précédente <- curseur
curseur <- suivant(curseur)
si (curseur <> NIL)
alors
suivant(cellule_précédente) <- suivant(curseur)
On suppose que chaque cellule de la liste liste contient les champs nom, prénom et note.
Ecrire un algorithme Mise_a_jour(liste, nom_recherché, prénom_recherché, note_à_mettre)
qui met la note note_à_mettre à l'étudiant de nom nom_recherché et de prénom
prénom_recherché dans la liste.
Mise_a_jour(liste, nom_recherché, prénom_recherché, note_à_mettre)
si (liste <> NIL)
alors
curseur <- liste
tant que (curseur <> NIL)
ET ((nom(curseur) <> nom_recherché) OU
(prenom(curseur) <> prenom_recherché))
faire curseur <- suivant(curseur)
si (curseur <> NIL)
alors
note(curseur) <- note_à_mettre
Quelques mots sur les conditions:
le contraire de (a OU b) est ((NON a) ET (NON b))
le contraire de (a ET b) est ((NON a) ET (NON b))
Rappel:
(NON VRAI) = FAUX
(NON FAUX) = VRAI
OU
quand nom(curseur) = nom_recherché ET prenom(curseur) = prenom_recherché
On arrête de parcourir la liste quand la condition précédent est vraie, autrement dit, on
parcourt la liste tant que la condition précédente est fausse, ce qui donne
tant que
(NON
((curseur = NIL)
46
OU
((nom(curseur) = nom_recherché) ET (prenom(curseur)=prenom_recherché))
ce qui donne avec les règles énoncées plus haut
tant que
((curseur <> NIL)
ET
((nom(curseur) <> nom_recherché) OU (prenom(curseur)<>prenom_recherché))
On suppose que l'on dispose de deux listes liste1 et liste2 triées dans l'ordre croissant. Ecrire
un programme qui réalise la fusion des ces listes en une liste elle même triée.
mettre deux curseurs sur liste1 et liste2 et toujours comparer le contenu des deux
curseurs en avançant d'un cran à la fois
mettre deux curseurs sur liste1 et liste2 et avancer un curseur tant que les contenus
sont inférieurs au contenu de l'autre curseur
copier la liste1 et insérer un par un les éléments de la liste2
Exemple : Supprimer
// supprimer l'élément de rang k d'une liste L
SI la liste L n'est pas vide ALORS
SI le rang k de suppression est valide ALORS
47
décaler les éléments e(k+1), …, e(n) vers la gauche;
SINON
afficher le message d'erreur "rang non valide";
FIN SI;
SINON
afficher le message d'erreur "liste vide";
FIN SI;
48
Nous avons ici un cas de structure de données récursive (SUIVANT étant un pointeur sur
enregistrement de même type)
Remarque
- Pour accéder à l'élément ei il faudra balayer séquentiellement les i-1 éléments qui
précédent (s'ils existent)
- Le passage d'une cellule à la cellule suivante, si L désigne l'adresse de la cellule
courante, s'écrira :
L L^.SUIVANT
Algorithme de l'opération supprimer
// supprimer l'élément de rang k d'une liste L
SI la liste L n'est pas vide ALORS
SI le rang k est égal à 1 ALORS
supprimer la première cellule;
SINON
rechercher séquentiellement la cellule k;
SI cette cellule k existe ALORS
supprimer la cellule;
SINON
afficher le message d'erreur "rang incorrect";
49
SI L != NULL ALORS
SI K = 1 ALORS
// suppression en tête de liste
L L^.SUIVANT;
SINON
// suppression dans la liste
50