Vous êtes sur la page 1sur 38

SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES

ALGORITHMIQUE ET STRUCTURES DES DONNEES

PLAN DU COURS
Chapitre Page

1. Généralités sur l’Algorithmique et la Programmation 2


1.1. Introduction générale et Définition de l’Algorithmique
1.2. Méthodologie et étapes de conception d’un Algorithme
1.3. Catégories et caractéristiques des Langages de Programmation

2. Variables, Constantes et Types de données de base 6


2.1. Les Types de données de base
2.2. Les Variables
2.3. Les Constantes
2.4. Opérateurs, expressions et instructions

3. Opérations d’Entrée-Sortie : Saisie et Affichage 10


3.1. Opération de Saisie de données
3.2. Opérateur d’Affichage de données

4. Structures de Contrôle 12
4.1. Structures Conditionnelles ou Alternatives
4.2. Structures Itératives ou Répétitives

5. Procédures et Fonctions 18
5.1. Procédures et Passage de paramètres
5.2. Fonctions, Appel de fonction et Récursivité
5.3. Sous-programmes et Portée des variables

6. Tableaux et Tri de données 28


6.1. Tableaux à une dimension
6.2. Tableaux Multidimensionnels
6.3. Algorithmes de Tri des Tableaux

7. Introduction aux Structures de Données Avancées (en annexe)


7.1. Notions de Pointeurs et de Piles
7.2. Notions de Fichiers et d’Enregistrements
7.3. Notions de Listes et d’Arbres
7.4. Notions de Structures et de Classes

8. Travaux Dirigés d’ALGO (en annexe)

CYCLE INGENIEUR et DESS INFORMATIQUE p 1/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
Chapitre 1 : Généralités sur l’Algorithmique et la Programmation

1.1 Introduction générale et Définition de l’Algorithmique

Pour rappel, un ordinateur est une machine électronique programmable servant


au traitement automatique de l’information codée sous forme binaire (0 / 1).

Contrairement à la vision des films de science-fiction, un ordinateur est une machine


totalement dénuée d'intelligence. Il n'est capable de traiter qu’un nombre limité d'instructions:
il faut tout lui dire, car il fait tout au pied de la lettre, sans réfléchir.
Pourtant, contrairement aux autres machines qui sont dédiées à un nombre limité de tâches,
l'ordinateur est potentiellement capable d’effectuer une infinité de tâches concernant le traitement
rationnel de l’information.
Alors comment une telle machine peut-elle traiter autant de problèmes différents?
C'est que, grâce aux actions de base qu'elle sait réaliser, il est possible en les assemblant de façon
pertinente, de résoudre la plupart des problèmes concernant le traitement de l'information. Il
suffit de lui indiquer l'ordre dans lequel il faut qu'il effectue ces actions basiques et avec quelles
données. Ces ordres élémentaires sont appelés instructions et sont rassemblées au sein d’un
programme. Comme l'ordinateur a l'avantage d'exécuter très rapidement et sans erreurs les
instructions qu'on lui donne, il exécute beaucoup de traitements complexes plus vite et plus
sûrement qu'un homme.

Pour donner des ordres à l'ordinateur, il est nécessaire de pouvoir communiquer avec lui.
Cette communication passe par un langage de programmation, dans lequel est écrit le
programme.

Un programme est un assemblage et un enchaînement d’instructions


élémentaires écrit dans un langage de programmation, et exécuté par un ordinateur ou
assimilé afin de traiter les données d’un problème et renvoyer un ou plusieurs résultats.

Un algorithme représente l'enchaînement des actions (instructions) nécessaires


pour faire exécuter une tâche (résoudre un problème) à un ordinateur. Il consiste en la
description d’un certain nombre d’opérations élémentaires selon un ordre logique
permettant de résoudre un problème sur des données en un nombre fini d’étapes.

Etymologiquement, le mot algorithme est dérivé du nom d'un mathématicien perse qui a
vécu au IXème siècle, Mohammed al-Khwârizmî (en latin Algorismus). Il a proposé un ensemble
d'opérations élémentaires à exécuter séquentiellement, pour additionner, soustraire, multiplier et
diviser des nombres décimaux.
Un algorithme s'écrit le plus souvent en pseudo-langage de programmation appelé langage
algorithmique. Un algorithme n'est donc exécutable directement par aucune machine. Mais il a
l'avantage d'être facilement traduisible dans tous les langages de programmation.

L'algorithmique, qui est l'art d'écrire des algorithmes, permet de se focaliser sur la
procédure de résolution du problème sans se soucier des spécificités d'un langage particulier.
Pour résoudre un problème, il est vivement conseillé de réfléchir d'abord à l'algorithme
avant de programmer, c'est à dire d'écrire le code en langage de programmation sur un ordinateur
car en fait, un programme est la traduction d’un algorithme dans un langage de programmation.

IMPORTANT : Avant de se mettre devant la machine, on doit écrire les algorithmes !!!

CYCLE INGENIEUR et DESS INFORMATIQUE p 2/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES

1.2 Méthodologie et étapes de conception d’un Algorithme

Un bon programme informatique doit être :


o lisible
o fiable
o maintenable
o réutilisable
o portable
o correct (donner les résultats escomptés)
o efficace (le moins complexe possible)
o faire face à des contraintes d’ordre «économiques » :
¾ Temps d’Exécution le plus court possible
¾ Espace Mémoire requis le plus faible possible…

Pour ce faire, on a besoin d’une méthodologie de travail :

o La conception d’un programme informatique doit passer par les 3 phases suivantes :
1. 1 Problème => Enoncé : La spécification
2. 2 Enoncé => Algorithme : La résolution
3. Algorithme => Programme : Le codage
o Si le problème est bien posé, l’énoncé doit permettre de définir sans ambiguïté :
¾ L’entrée (données du problème)
¾ La sortie (résultats recherchés)
¾ Les relations (éventuelles) entre les données et les résultats
o Voici les principes pour écrire un algorithme de qualité :
¾ Abstraire (Repousser le plus loin possible l’écriture de l’algorithme)
¾ Décomposer (Décomposer la résolution en une suite de “sous-problèmes” que l’on
considère comme résolus)
¾ Combiner (Résoudre le problème par combinaison des abstractions des “sous-
problèmes”)
o Pour fournir une solution au problème, il faut donc un moyen d’exprimer cette solution
(l’algorithme) à l’aide d’un langage qui doit être :
¾ formel (pas d’ambiguïtés),
¾ lisible et concis,
¾ indépendant de tous langages informatiques
¾ coordonné selon les principes suivants :
9 les entités manipulées sont désignées et typées
9 suite ordonnée d’actions modifiant l’´etat d’un programme, pour passer :
ƒ de l’´etat initial -le problème -
ƒ à l’´etat final - la solution au problème-

CYCLE INGENIEUR et DESS INFORMATIQUE p 3/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES

3.1 Catégories et caractéristiques des Langages de Programmation

On classe souvent les langages de programmation en trois "générations": la première regroupe les
langages machine, la seconde les langages d'assemblage et la troisième les langages évolués.

o Le Langage Machine

Les instructions emmagasinées dans la mémoire de l'ordinateur et exécutées par l'unité de


traitement sont représentées sous la forme de chaînes de chiffres binaires. On dit qu'elles sont
exprimées en langage machine. Le langage machine constitue le seul langage réellement «compris»
par l’ordinateur, tous les autres correspondant à des formes de structuration du langage humain.
Cette forme de programmation, lente et fastidieuse, était source de nombreuses erreurs.
Elle n'est utilisée aujourd'hui que dans quelques cas isolés par :
¾ Les hackers, pour enlever une protection d'un programme.
¾ Les virus pour infecter un programme exécutable.
¾ Les patchs pour corriger un programme exécutable.

Cependant, dans le cadre de l'écriture d'un programme important et complexe, elle est
quasi inutilisable et surtout inutile. On programmera donc dans des langages de programmation
plus commodes à employer : les langages d’assemblage et les langages évolués.

o Les langages d'assemblage

Les langages d’assemblage ont permis l’écriture des instructions du langage machine sous
forme symbolique; la traduction en binaire étant assurée par un programme, fourni par le
constructeur, appelé ASSEMBLEUR.
Les langages d'assemblage sont des langages de programmation les plus proches du
langage machine, où chaque instruction correspond à une instruction machine unique. Bien qu'ils
introduisent certains allégements (codes opératoires mnémoniques, adresses en base 10 ou 16,
utilisation d'étiquettes pour les ruptures de séquence...), ils ne solutionnent pas les autres
inconvénients du langage machine (extrême pauvreté des instructions, liaison étroite en le langage
et le type d'ordinateur). En effet, le jeu d’instructions d’un tel langage est associé à un certain type
de processeur. Ainsi, les programmes écrits en langage assembleur pour un processeur particulier
doivent être réécrits pour tourner sur un ordinateur équipé d’un processeur différent. Après
écriture d’un programme en langage d'assemblage, le programmeur fait alors appel à l’assembleur
spécifique du processeur, qui traduit ce programme en instructions machine.

Cependant, les langages d'assemblage sont encore utilisés aujourd'hui dans quelques cas :
¾ -Quand la vitesse d'exécution est primordiale (par exemple, les jeux vidéo ou
l'informatique en temps réel).
¾ Pour accéder directement à certains périphériques (programmation d'une carte
vidéo, par exemple).
¾ Quand la taille du programme est vitale (par exemple, l'informatique embarquée ou
les virus).
Pour pallier aux inconvénients des langages d'assemblage, on a imaginé de créer des
langages dits évolués, écrits avec l’alphabet usuel, comportant des sigles ayant une valeur
mnémotechnique pour l’utilisateur. Pour chaque langage et chaque type de machine, on a rédigé
un programme (baptisé compilateur) qui assure la traduction de tout texte écrit avec le langage
évolué en un texte en langage machine, en garantissant la fidélité de la traduction : les actions
exécutées par la machine sont effectivement celles qui sont décrites par le langage évolué.

CYCLE INGENIEUR et DESS INFORMATIQUE p 4/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
On distingue 5 catégories de langages dits évolués :

o Les langages procéduraux ou impératifs

Les langages impératifs ou procéduraux ne s’éloignent des langages machines que par leur
richesse d’expression ; ils en gardent la structure de calcul. Ces langages sont basés sur :
¾ Des variables avec des types de données définis
¾ Le contrôle de l’enchainement à travers des structures de contrôle
¾ Des procédures et des fonctions qui sont des subdivisions du programme ou des sous-
programmes
Exemples de langages procéduraux : Pascal, C, Delphi, …

o Les langages objets

La Programmation Orientée Objets est une extension de la programmation impérative.


L'idée de base est d'associer le code et les données dans une entité appelée "objet".
Si le concept de variable est assimilable à une abstraction de la notion de "case mémoire" dans la
programmation procédurale, avec la programmation Objets, on avance encore dans l'abstraction.
Aux cases mémoires on associe, en plus du nom et des types de données, du code exécutable. Il faut
voir un objet - au sens informatique - comme un ensemble de variables (les propriétés) et des
instructions qui lui sont associées (les méthodes).
Exemples de langages objets : C++, Java, Visual Basic.NET, …

o Les langages fonctionnels ou récursifs

La programmation procédurale est étroitement liée à la perspective constructiviste des


mathématiques, qui définit une fonction par la suite des opérations à effectuer pour la calculer.
Elle s’opposait à la perspective intuitionniste, pour laquelle une définition implicite suffit à
prouver l’existence d’une fonction. C’est la voie qu’inaugura John Mac Carthy, vers 1960, en créant
le langage Lisp (List Processing Language) basé sur les prédicats. Elle se fonde, elle aussi, sur la
récurrence, mais en l’exploitant d’une autre façon.
Dans les langages fonctionnels, la fonction est l'objet de base. On peut, par exemple, passer
une fonction en paramètre ou une fonction peut renvoyer une autre fonction.
Exemples de langages fonctionnels: Caml, Lisp, Logo, …

o Les langages logiques ou déductifs

Pour faire résoudre un problème par un ordinateur, il faut en fournir une méthode explicite
de calcul si on utilise la programmation impérative, une méthode implicite par la programmation
récursive. Dans les deux cas, il faut trouver une relation de récurrence exploitable. La
programmation logique, inventée par le Français Alain Colmerauer, fait sortir de cet univers. Elle
vise à donner à l’ordinateur non un algorithme de résolution, mais des informations sur les
données et les relations qui les lient aux résultats. Nous sortons donc du domaine où programmer
veut dire trouver une méthode de résolution. Il n’y a plus création d’algorithme. On fixe les
relations entre des éléments. On donne certains éléments, le système (dit expert) trouve tous ceux
qui leur sont liés par ces relations. Pour y parvenir, l’ordinateur doit être muni d’un programme
complexe appelé moteur d’inférence qui cherche quelles règles appliquer et, au besoin, quelles
variables supplémentaires mettre en jeu. Il relève des théories de la démonstration automatique.
Exemple de langage logique : Prolog, …

NB : A ces 4 catégories de langages évolués, on ajoute désormais une 5è catégorie avec


l’avènement du Web : les langages déclaratifs. Exemple : XML, HTML, WML.
Concernant l’exécution des langages évolués, on distingue deux modes : les langages
compilés (ex : C, C++, VB, …) et les langages interprétés (ex : Perl, Javascript, PHP, …).

CYCLE INGENIEUR et DESS INFORMATIQUE p 5/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
Chapitre 2 : Variables, Constantes et Types de données de base

2.1 Types de données de base

En algorithmique, chaque objet manipulé doit correspondre à un type de données.


Les types de données permettent de classer les objets selon :
¾ L’ensemble des valeurs que peut prendre l’objet
¾ L’ensemble des opérations permises sur ces valeurs

Ces types obéissent aux règles suivantes :


¾ Tous les types ont un nom
¾ Tous les objets ont un type (qui doit être déclaré)

On peut classer les types de données suivant deux points de vue


¾ Prédéfinis / Définis explicitement :
9 Prédéfinis : Booléen, Entier, Réel, Caractère, Chaîne de caractères, …
9 Définis explicitement : intervalle, énuméré, tableaux, structures,…
¾ Elémentaires / Composites :
9 Elémentaires : Booléen, Entier, Réel, Caractère, intervalle, énuméré…
9 Composites : Chaîne de caractères, tableaux, structures,…

En algorithmique, on distingue les principaux types de données de base suivants :


¾ les caractères (lettres alphabétiques, chiffres, ponctuations, code des opérations,
espace,… et plus généralement toutes les touches que l'on peut trouver sur un clavier)
¾ les chaînes de caractère ou alphanumériques (ensembles de caractères)
¾ les nombres ou numériques qui peuvent se subdiviser en deux catégories :
9 les entiers (les nombres sans virgule : entiers long)

Type Numérique Plage

Byte (octet) 0 à 255

Entier simple -32 768 à 32 767

Entier long -2 147 483 648 à 2 147 483 647

9 les réels ou flottants (les nombres à virgule et sans virgule)

Type Numérique Plage

Réel simple -3,40E38 à -1,40E-45 pour les valeurs négatives


1,40E-45 à 3,40E38 pour les valeurs positives

Réel double 1,79E308 à -4,94E-324 pour les valeurs négatives


4,94E-324 à 1,79E308 pour les valeurs positives

¾ les booléens (qui n'ont que deux valeurs possibles, 0 ou 1 ou encore VRAI ou FAUX)
¾ les dates (dates : jour, mois, année et heures sous plusieurs formats)

NB : On trouve quelques fois un autre type : le type monétaire pour les valeurs monétaires.
De plus, il est également possible pour le Programmeur de créer des types de données
personnalisés.

CYCLE INGENIEUR et DESS INFORMATIQUE p 6/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
2.2 Les Variables

Les données d'un programme doivent être récupérées en mémoire centrale, à partir du
clavier ou d'un fichier par exemple, pour pouvoir être traitées par le processeur qui exécute le
programme. Ainsi, toutes les données d'un programme sont mémorisées en mémoire centrale, dans
des sortes de cases que l'on appelle variables.

Une variable peut être représentée par une case mémoire, qui contient la valeur d'une
donnée. Chaque variable possède un nom unique appelé identificateur par lequel on
peut accéder à son contenu.

Par exemple, on peut avoir en mémoire une variable Prix et une variable Quantité qui
contiennent respectivement les valeurs 1000 et 15 :

1000 15

Prix Quantité

Attention à ne pas confondre la variable et son contenu : une variable est un contenant,
c'est à dire une sorte de boîte, alors que le contenu d'une variable est une valeur correspond à un
type de données (numérique, alphanumérique, booléenne, …)

Deux variables peuvent avoir la même valeur, mais une variable ne peut pas avoir plusieurs
valeurs en même temps. En revanche, la valeur d'une variable peut varier au cours du programme.
L'ancienne valeur est tout simplement écrasée et remplacée par la nouvelle.

o Déclaration des variables :

Pour qu'un programme puisse utiliser une variable, il faut au préalable que cette variable
ait été déclarée, c'est-à-dire que le programme lui ait réservé une place en mémoire et ait attribué
l'identificateur à cette place. Mais toutes les variables n'ont pas besoin de la même place en
mémoire. Un grand nombre prend plus de place qu'un caractère. Selon le type de l'objet, il faudra
lui réserver plus ou moins de place: c'est pourquoi il faut déclarer le type des variables et pas
seulement leur nom. Par ailleurs, selon le type des variables, les opérations possibles seront
différentes.
Ainsi, pour déclarer une variable, on utilise le mot clé « Variable » ou « VAR » et on indique :
¾ son identificateur (son nom)
¾ son type (sa taille)
La syntaxe de déclaration de variables en algorithmique est donc :
Variable <liste d’identificateurs séparés par des virgules> : type

Exemples :
Variables Nombre1, nombre2: entiers
Sexe : caractère
Nom, prénoms : chaînes de caractères

L’instruction qui permet d’attribuer une valeur à une variable ou modifier cette valeur, est
l’affectation. En algorithmique, cette instruction se note avec le signe Å. Par exemple : nÅ2.

Remarques : Un identificateur peut être composé de lettres et de chiffres mais il ne peut pas
commencer par un chiffre et ne peut comporter d'espaces. L'identificateur des variables doit être
suffisamment signifiant pour qu'on reconnaisse leur fonction aisément. Par exemple pour des
variables représentant un prix et une quantité, évitez a et b mais utilisez plutôt Prix et Quantité.

CYCLE INGENIEUR et DESS INFORMATIQUE p 7/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
2.3 Les Constantes

Les variables dont la valeur ne change pas au cours de l'exécution du programme sont
appelées variables constantes ou plus simplement constantes. Les constances sont donc des
entités dont la valeur est figée. Une constante a également un type et une valeur.
On distingue deux types de constantes :
¾ Constante implicite : ce sont les valeurs de faite. Par exemple : 10, ”toto”, ’a’
¾ Constante explicite : ce sont les constantes définies explicitement. Par exemple :
LIMITEVAL (une valeur limite donnée), DATEANNIV (une date d’anniversaire)

o Déclaration de constantes :

Pour déclarer une constante, on utilise le mot clé « Constante » ou « CONST » et on indique :
¾ son identificateur (son nom)
¾ son type (facultatif)
¾ et sa valeur
La syntaxe de déclaration de constantes en algorithmique est donc :
Constante (<identificateur : type>) Å valeur

Exemples :
Constantes (TVA : entier) Å 18%
(DateNoel : date) Å ’25-12-2006’

NB : La déclaration des variables et des constantes en algorithmique se fait généralement en


début du programme ou des sous-programmes (procédures et fonctions).

2.4 Opérateurs, expressions et instructions

Un opérateur est un symbole / mot qui permet d’associer deux ou plusieurs opérandes (variables
ou constantes) pour former une expression. Une expression a un donc un type et une valeur.

Voici une liste non-exhaustive des opérateurs utilisés en algorithmique, par type de données :

CYCLE INGENIEUR et DESS INFORMATIQUE p 8/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
Un algorithme décrit une suite d’actions, qui fait passer de la situation initiale (celle des données)
à la situation finale (celle des résultats). Chaque action élémentaire est appelée instruction.
L'exécution d'un programme est constituée d'échanges d'informations en mémoire et de calculs.
Une instruction est un ordre élémentaire que peut exécuter directement l'ordinateur. Une
instruction revient souvent à déplacer une information d'un endroit à un autre de la mémoire.

Un algorithme est donc un ensemble fini d’instructions séparées généralement par des
points-virgules ou des retours-chariots (retours à la ligne).

Les informations (données) manipulées par les instructions peuvent prendre plusieurs formes :
¾ des variables proprement dites
¾ des constantes explicites
¾ des constantes implicites (valeurs littérales écrites telles qu'elles dans le programme)
¾ des messages (libellés) destinés à l'utilisateur (quelles sont les données à entrer, quels
résultats sont affichés…), qui sont des valeurs littérales particulières
¾ des expressions complexes (combinaisons de variables, constantes et valeurs littérales)
avec des opérateurs. Exemple : 2 * rayon * 3.14

Les instructions élémentaires les plus courantes sont :


¾ l'affectation: le fait de donner une nouvelle valeur à une variable
¾ l'affichage sur l'écran
¾ la saisie à travers le clavier
D'autres instructions permettent de lire et d'écrire sur d'autres périphériques d’entrée-sortie.

La programmation procédurale repose sur le couple situation-action. Le programme décrit la suite


d’actions qui fait passer de la situation initiale à la situation finale. Pour établir la validité d’un
programme, on détermine la suite de situations qu’il engendre. Si, pour toutes les données
possibles, la situation finale est celle que l’on attend, le programme est considéré juste.

o Structure générale d’un algorithme :

ALGORITHME NomAlgo
// Déclarations de variables et constantes

Variables variable1, variable2: type1


Variable3 : type3

Constantes (const1 : type1) Å val1
(const2 : type2) Å val2

DEBUT
/* Commentaires de description du code sur
plusieurs lignes*/
// Lecture des données d’entrée
Instruction1
Instruction 2
// Code des Procédures et Fonctions

Instruction n
// Code de la procédure principale : Appel des Fonctions et Affichage des résultats
FIN

CYCLE INGENIEUR et DESS INFORMATIQUE p 9/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
Chapitre 3 : Opérations d’Entrée-Sortie : Saisie et Affichage

Au début d’un programme, les variables n’ont pas encore reçues de valeur; on dit qu’elles
sont indéfinies. Toutes les variables doivent être initialisées, c’est-à-dire recevoir une valeur
initiale, avant leur utilisation. Sinon, lorsqu’on utilise une variable indéfinie (qui n’a pas encore
reçue de valeur), le comportement du programme peut être aléatoire.

De là vient la nécessité de toujours bien initialiser les variables avant d’utiliser leur valeur.
L’initialisation s’effectue généralement au début du programme, juste après les déclarations. Elle
prend la forme d'une simple affectation ou d’une saisie au clavier. Pendant ou à la fin de
l’exécution du programme il s’avère souvent nécessaire d’afficher à l’écran le contenu des
variables ou expressions dérivées.

3.1 Opération de Saisie de données

L’instruction de saisie permet de communiquer des données au programme. Cette


instruction assigne une valeur entrée au clavier dans une variable. Autrement dit, elle
place en mémoire les informations saisies. Tant que l'utilisateur n'entre rien au clavier,
le déroulement du programme est stoppé.

La saisie d'une variable au clavier permet, comme l'initialisation d'affecter une valeur
initiale à une variable : donc les variables saisies n'ont pas à être initialisées mais elles doivent
être déclarées au préalable pour préciser à quel type correspond la donnée saisie.

¾ Syntaxe :
Saisir variable1 [, variables2, …]

¾ Exemples :
Saisir x

(Lit la valeur saisie au clavier et l'affecte à la variable x)

Saisir x, y

(Lit la 1ère valeur saisie au clavier et l'affecte à x, puis lit la 2ème saisie et l'affecte à y)

¾ Utilité de la saisie :

On pourrait être tenté de dire que l’instruction de saisie est inutile car on dispose déjà un
moyen d’attribuer une valeur aux variables, par l’instruction d’affectation. Mais en fait,
l’instruction de saisie (ou de lecture sur un périphérique autre que le clavier) est indispensable
pour permettre d’utiliser le même programme sur des données différentes sans avoir à changer les
valeurs du programme à chaque fois.

L’un des avantages de l’instruction de saisie, c’est que le choix de la valeur se fait en cours
d’exécution du programme. On peut donc utiliser le programme autant de fois que l’on veut avec
des données différentes sans avoir à modifier le programme.

Sans instruction de saisie (ou de lecture sur un périphérique quelconque), un


algorithme fournirait toujours le même résultat.

CYCLE INGENIEUR et DESS INFORMATIQUE p 10/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
3.2 Opérateur d’Affichage de données

La plupart des programmes nécessitent de communiquer à l’utilisateur un certain nombre de


résultats par l’intermédiaire d’un périphérique. Pour cela, ils utilisent des instructions d'affichage.

L'instruction d'affichage permet de fournir des résultats sous forme directement


compréhensible pour l'utilisateur à travers l'écran.

¾ Syntaxe :
Afficher expression1, [expression2, …]

¾ Exemples :
Afficher Nom

(Permet d'afficher la valeur de la variable Nom à l'écran. Si Nom est une chaîne qui
vaut "toto", cette instruction affichera toto à l'écran)

Afficher "Bonjour!"

(Permet d'afficher la chaîne littérale Bonjour! à l'écran)

Afficher A, B
(Quand on veut afficher deux objets à la suite, on les sépare d'une virgule)

On peut mélanger l'affichage de valeurs littérales et de variables. Cela est particulièrement


utile si on veut voir apparaître un libellé (texte accompagnant la saisie des données ou
l'édition des résultats, permettant de guider l'utilisateur).

¾ Exemple :
Afficher "Voici les résultats : x vaut ", x, " et y vaut", y

Nous aurons donc à l’écran (en supposant que les valeurs de x et y sont
respectivement 5 et 10) : Voici les résultats : x vaut 5 et y vaut 10

¾ Exemple complet sur la Saisie et l’Affichage :

CYCLE INGENIEUR et DESS INFORMATIQUE p 11/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
Chapitre 4 : Structures de Contrôle

On distingue généralement deux types de structures de contrôle : les structures


conditionnelles ou alternatives et les structures itératives ou répétitives.

4.1 Structures Conditionnelles ou Alternatives

Une structure conditionnelle ou alternative est un ensemble d’instructions particulières dont


l’exécution dépend de la vérification ou non d’une ou plusieurs conditions.
On en distingue deux variantes :

1. La structure alternative simple ou sélection à choix unique

La structure alternative se présente en général sous la forme suivante :

Si condition Alors
Séquence d'instructions 1
Sinon
Séquence d'instructions 2
Finsi

Où condition est une expression logique ou booléenne dont la valeur conditionne le choix
d'un des deux ensembles d'instructions. Cette condition peut être soit vraie soit fausse. Si
l'expression est vraie, la première séquence d'instruction sera exécutée et la seconde sera ignorée;
si l'expression est fausse, seule la seconde séquence d'instructions sera exécutée.

Le mot Sinon indique où se termine la première séquence d'instructions et où commence la


seconde. Le mot Finsi indique où se termine la seconde séquence d'instructions.

Dans certains cas, lorsque la condition est fausse, aucune instruction ne doit être exécutée.
La structure alternative s'exprime alors plus simplement sous la forme:

Si condition Alors
Séquence d'instructions
Finsi

Remarques :
o Quelle que soit la séquence choisie et exécutée, les instructions qui suivent Finsi seront
exécutées.
o Chacune des séquences d'instructions d'un Si ... Finsi peut contenir des Si...Finsi à son tour.
On dit alors que les structures sont imbriquées.
o Pour faire apparaître plus clairement la structure, on écrit les séquences d'instructions
légèrement en retrait des mots-clefs (Si, Alors, Sinon, Finsi). On dit qu'on indente le texte de
l'algorithme.

¾ Exemple : Comparaison de deux nombres


Si (a<b) Alors
maxÅb
Sinon
maxÅa
Finsi

CYCLE INGENIEUR et DESS INFORMATIQUE p 12/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
2. La structure alternative multiple ou sélection à choix multiple

La structure alternative multiple ou sélection à choix multiple permet de choisir le


traitement à effectuer en fonction de la valeur ou de l'intervalle de valeur d'une variable ou d'une
expression. Lorsque l’on veut comparer la même variable (de type Entier, Naturel, Caractère) a des
valeurs successives on peut donc remplacer la succession de Si. . . Alors. . . Sinon par :

SelonQue identificateur
valeur1 : séquence d'instructions 1
valeur2 : séquence d'instructions 2

intervallevaleuri : séquence d'instructions i

valeurn : séquence d'instructions n
autre : séquence d'instructions par défaut
Finselon

Si l’identificateur a la valeur valeuri ou est incluse dans intervallevaleuri, la i ème séquence


d'instructions est exécutée puis il y a passage aux instructions qui suivent le mot Finselon. Si
aucune valeur n’est vérifiée, on exécute la séquence d'instructions qui suit le mot autre.

¾ Exemple1 :
SelonQue mois
1 : Afficher "Janvier"
2 : Afficher "Février"
3 : Afficher "Mars"
4 : Afficher "Avril"
5: Afficher "Mai"
6 : Afficher "Juin"
7 : Afficher "Juillet"
8 : Afficher "Aout"
9 : Afficher "Septembre"
10 : Afficher "Octobre"
11: Afficher "Novembre"
12: Afficher "Décembre"
autre : Afficher "Un numéro de mois doit être compris entre 1 et 12"
Finselon

¾ Exemple2:
SelonQue montant
<1000 : TauxTVAÅ1
≥1000 et < 3000: TauxTVAÅ2
≥3000 et < 10000: TauxTVAÅ3
≥ 10000: TauxTVAÅ4
autre : TauxTVAÅ5
FinSelon

CYCLE INGENIEUR et DESS INFORMATIQUE p 13/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES

4.2 Structures Itératives ou Répétitives

L'intérêt d'utiliser un ordinateur n'apparaît clairement que lors de la manipulation de


données nombreuses ou traitées de manière répétitive.
S'il est théoriquement possible de se contenter d'une seule structure de répétition, bien
choisie, pour exprimer tous les algorithmes, l'expérience a montré l'utilité d'en définir plusieurs,
chacune bien adaptée à des circonstances particulières. Ce sont les boucles Pour, TantQue et
Répéter.

1. La boucle « Pour »

La boucle Pour permet de répéter l’exécution d’un ensemble d’instructions en un nombre


connu de fois. La syntaxe générale de cette boucle est la suivante :

Pour variableÅborneDepart à borneArrivee [pasde p (par defaut p=1)] Faire


Séquence d’instructions
Finpour

Les mots Faire et Finpour 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 ou compteur et les valeurs que prendra cette variable :
une première valeur ou valeur initiale indiquée après le symbole d’affectation, une dernière valeur
ou valeur finale indiquée après le mot à. Ces valeurs doivent être de type numérique.

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 sort de la boucle et on passe à l'instruction qui suit le mot Finpour.
Après chaque exécution du corps de la boucle, la variable de contrôle est incrémentée de
p (augmentée de p unités) si la valeur de p (incrément) indiquée est positive ou, par défaut,
incrémentée de 1 si p n’est pas indiqué. Par convention, lorsque l'incrément est égal à 1, il n'est
pas indiqué. Toutefois, si on veut faire varier la variable de contrôle par valeurs décroissantes, la
valeur de p doit être négative. Dans ce cas, on dit que la variable de contrôle est décrémentée de
p (diminuée de p unités).

L'exécution de la boucle s'arrête :


o lorsque la variable de contrôle a une valeur supérieure (strictement) à la dernière
valeur si l'incrément est positif
o lorsque la variable de contrôle a une valeur inférieure (strictement) à la dernière
valeur si l'incrément est négatif.

¾ ATTENTION : Il est recommandé de ne pas modifier la valeur de la variable de contrôle à


l'intérieur de la boucle.

¾ Exemple : Somme des nombres pairs inférieurs ou égal à 20

SommeÅ0
Pour iÅ0 à 20 pasde 2 Faire
SommeÅsomme+i
Finpour
Afficher(‘’la somme vaut’’,Somme)

CYCLE INGENIEUR et DESS INFORMATIQUE p 14/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
2. La boucle « TantQue »

La boucle TantQue permet de d’effectuer l’exécution d’un ensemble d’instructions en un


nombre inconnu de fois, tant qu’une condition est vérifiée. Sa syntaxe générale est la suivante :

TantQue condition Faire


Séquence d’instructions
Fintantque

En premier lieu, la condition, exprimée sous la forme d’une expression logique, est évaluée
(il faut donc veiller à initialiser sa valeur avant l'entrée dans la boucle): si sa valeur est vrai, le
corps de la boucle est exécuté puis la condition 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 sort de la boucle et on exécute
l'instruction qui suit Fintantque. Il peut arriver que la boucle ne soit jamais du tout exécutée.

Il est à noter que parfois, il est plus simple de déterminer les raisons d'arrêter le processus
répétitif que celles de continuer. Dans ce cas, il est préférable d'exprimer la condition sous la forme
NOT (négation de la condition d'arrêt). La forme de ce type de boucle devient alors :

TantQue NOT condition Faire


Séquence d’instructions
Fintantque

¾ Exemple1 : Somme des nombres pairs inférieurs ou égal à 20

SommeÅ0
iÅ0
TantQue ( i <= 20) Faire
SommeÅsomme+i
iÅi+2
Fintantque
Afficher(‘’la somme vaut’’,Somme)

¾ Exemple2 : Somme d’une suite de données saisies par l’utilisateur

CYCLE INGENIEUR et DESS INFORMATIQUE p 15/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
3. La boucle « Répéter »

Comme la boucle TantQue, la boucle Répéter est une boucle répétitive utilisée lorsque le
nombre de fois que la séquence d'instructions doit être exécutée est inconnu au moment où cette
séquence est abordée pour la première fois mais le corps de la boucle est toujours exécuté au
moins une fois. La syntaxe de cette boucle est :

Répéter
Séquence d’instructions
Jusqua condition

Où condition est une expression logique qui exprime les raisons d'arrêter la boucle. Cette
expression 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 la condition 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 Jusqua.

¾ ATTENTION : Si ceci correspond tout à fait à l'usage familier que nous faisons de
l'expression Répéter ... jusqu'à, le test effectué ici est la négation de celui utilisé dans la
boucle TantQue et ceci peut parfois prêter à confusion.

¾ Exemple : Somme des nombres pairs inférieurs ou égal à 20

SommeÅ0
iÅ0
Répéter
SommeÅsomme+i
iÅi+2
Jusqua (i > 20)
Afficher(‘’la somme vaut’’,Somme)

¾ REMARQUES : La boucle Pour est dite « déterministe » car le nombre d’itérations est
connu à l’avance, tandis que les boucles TantQue et Répéter sont dites « non
déterministes » car leur nombre d’itérations n’est pas connu à l’avance.

CYCLE INGENIEUR et DESS INFORMATIQUE p 16/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
¾ DANS QUELS CAS CHOISIR UNE BOUCLE POUR ou TANTQUE ou REPETER ?

¾ EXEMPLE GENERAL : CALCUL DU PGCD AVEC L’ALGORITHME D’EUCLIDE

o Enoncé :
Etant donnés deux nombres entiers m et n positifs ou nuls, on veut 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 PGCD de m et n.

o Résolution pratique :
Pour m=1386 et n=140, on a successivement:
1386 = 140 * 9 + 126
140 = 126 * 1 + 14
126 = 14 * 9 + 0
Et le PGCD de 1386 et 126 est bien 14.
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:
140 = 1386 * 0 + 140
1386 = 140 * 9 + 126
140 = 126 * 1 + 14
126 = 14 * 9 + 0
Et le PGCD est le même. L'ordre de m et n n'a donc pas d'importance.
o Ecriture de l’Algorithme :
Notre algorithme doit répéter le calcul du reste de la division d'un nombre par un autre.
Pour cela, 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 des instructions de l'algorithme suivant :
Algorithme EuclidePGCD:
Variables m,n,a,b,r,PGCD : entier
DEBUT
Saisir m, n
aÅm
bÅn
TantQue NOT(b= 0) Faire
r Å a mod b
a Åb
bÅr
Fintantque
PGCD Åa
Afficher "Le PGCD de",m,"et",n,"est",PGCD
FIN

CYCLE INGENIEUR et DESS INFORMATIQUE p 17/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
Chapitre 5 : Procédures et Fonctions

¾ Généralités sur les procédures et fonctions :

Lors de la conception d’un algorithme ou d’un programme informatique résolvant un


problème général, il est nécessaire de décomposer le problème en différents sous-problèmes moins
complexe à résoudre : on parle d’Analyse Descendante. Ces différents sous-problèmes peuvent être
résolus grâce à des sous-algorithmes ou sous-programmes particuliers appelés procédures et
fonctions.

En fait, on décompose l’algorithme en plusieurs parties plus petites qu'on assemble ensuite
pour former l'application finale. Les procédures et les fonctions permettent donc de découper un
gros algorithme en morceaux plus petits et relativement plus simples à coder et à comprendre, et
permettent surtout d'éviter de répéter plusieurs morceaux de code identiques. On parle de
programmation modulaire.

Comme un algorithme, une procédure ou une fonction possède un nom, des variables, des
instructions, un début et une fin. Mais contrairement à un algorithme, une procédure ou une
fonction n’est pas destinée à s'exécuter indépendamment d'un autre algorithme.
En effet, l'exécution d’une procédure ou une fonction sera demandée par un algorithme
principal ou par une autre procédure ou fonction grâce à une instruction spécifique qu'on nomme
APPEL. Cet algorithme principal contient l'ensemble des instructions prévues pour s'exécuter au
lancement de l'application et c’est lui qui se chargera de demander l'exécution des instructions se
trouvant dans les procédures et fonctions.

Lorsqu’un algorithme principal ou un sous-algorithme appelle un autre sous-algorithme,


cet algorithme passe "momentanément" le contrôle de l'exécution du traitement au sous-
algorithme. Un sous-algorithme est donc conçu pour faire un traitement bien défini, bien
délimité, si possible indépendamment du contexte particulier de l’algorithme appelant.

Le schéma ci-dessous décrit l’enchaînement des informations au sein d’un algorithme en


utilisant des sous-algorithmes correspondant à des procédures et des onctions :

CYCLE INGENIEUR et DESS INFORMATIQUE p 18/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
¾ Avantages des procédures et fonctions :

La programmation modulaire à l’aide des procédures et fonctions permet de :

o Mieux identifier les différents traitements contribuant au travail demandé


o Bien organiser l'enchaînement des étapes
o Résoudre les problèmes de façon progressive, module par module
o Faciliter la mise en place et la maintenance des algorithmes
o Ne pas répéter plusieurs fois une même séquence d’instructions au sein de l’algorithme
o Modifier le traitement lui-même sans changer le rôle particulier d'un module
o Enrichir le langage algorithmique en ajoutant de nouvelles fonctions ou procédures
prédéfinies et « prêtes à l’emploi » grâce notamment aux notions de bibliothèques de
composants réutilisables et de boites à outils.

¾ Utilisation des procédures ou fonctions :

Lors de la conception d’un algorithme, deux aspects apparaissent :


o La définition et l’écriture du code des procédures ou fonctions.
o L’appel des procédures ou fonctions au sein de l’algorithme.

L’écriture d’une procédure ou fonction peut s’effectuer en fonction de paramètres dits


formels utilisés dans la conception de celle-ci. Par contre au moment de l’utilisation de la
procédure ou fonction, ces paramètres seront remplacés par de véritables valeurs appelées
paramètres effectifs ou arguments.

¾ REMARQUES : En programmation événementielle, les procédures et les fonctions sont


dites événementielles car elles s’exécutent à la suite d'un événement (appuie d’une touche sur le
clavier, clic sur un bouton, fermeture d'une fenêtre, etc.). Celles que nous allons étudier sont d'un
autre type : elles ne sont pas exécutées suite à un événement, mais sont lancées par une
instruction dans un autre sous-algorithme ou par l’algorithme principal.

Le schéma ci-après illustre le mécanisme d’appel des sous-algorithmes :

CYCLE INGENIEUR et DESS INFORMATIQUE p 19/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES

5.1 Procédures et Passage de paramètres

¾ Définition et principe d’une procédure :

Une procédure est une suite d’instructions considérée comme un sous-algorithme et


destinée à réaliser une ou plusieurs actions. Elle peut prendre en arguments des paramètres pour
les utiliser dans ses calculs.
Une procédure ne retourne aucune valeur explicitement mais elle peut manipuler (et
éventuellement modifier) les variables "globales'' de l’algorithme.

¾ Syntaxe de déclaration d’une procédure

La déclaration d’une procédure se fait par le mot clé « procédure » suivi du nom de la
procédure suivi de la déclaration des paramètres formels de la procédure mis entre parenthèses et
séparés par des virgules. Ensuite, suit on déclare les variables «locales» de la procédure puis on
place les instructions de la procédure entre début et fin.

Ainsi, voici la syntaxe correspondant à la déclaration d’une procédure :


Procédure NomProcedure ({E/S} parametre1:Type1, {E/S} parametre2:Type2, …)
[Déclaration des variables locales]
DEBUT
Liste des instructions de la procédure
FIN
¾ Définition des paramètres formels d’une procédure :

Les paramètres sont des variables déclarées dans l'en-tête d’une procédure ou une fonction,
avec leur type (entier, chaîne,…) et leur nature (donnée en entrée / résultat en sortie), dont les
valeurs sont fournies soit en entrée soit en sortie. On parle de paramètres formels.
Les procédures admettent trois types de paramètre formels. On préfixe donc le paramètre
formel dans la déclaration par :
o Entrée ou E pour un passage de paramètre en entrée : dans ce cas, le paramètre constitue
une donnée pour la procédure et toutes les modifications effectuées sur ce paramètre dans
la procédure ne seront pas effectives pour le reste de l’algorithme
o Sortie ou S pour un passage de paramètre en sortie : dans ce cas, le paramètre constitue un
résultat pour la procédure et ne possède pas de valeur initiale. La première instruction de la
procédure qui utilise ce paramètre doit donc l'initialiser. Toutes les modifications effectuées
ensuite sur ce paramètre dans la procédure perdurent après l'appel de la procédure.
o Entrée/Sortie ou E/S pour un passage de paramètre en entrée/sortie : dans ce cas, le
paramètre constitue à la fois une donnée et un résultat. Il possède une valeur initiale et
toutes les modifications effectuées sur lui perdurent après l'appel de la procédure.

Une procédure peut aussi ne pas nécessiter de paramètre. Dans ce cas, la liste des paramètres
reste vide. Par défaut, les paramètres d'une procédure sont en Entrée.

¾ Exemple1 : Procédure permettant de calculer et afficher la somme de deux entiers A et B


définis comme paramètres en entrée :

Procédure Somme(Entrée A, B : entier)


Variable S : entier
Début
SÅA+B
Afficher ‘’La somme des deux nombres est’’, S
Fin

CYCLE INGENIEUR et DESS INFORMATIQUE p 20/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
¾ Exemple2 : Procédure qui retourne à travers deux paramètres de sortie Min et Max la
valeur minimale et la valeur maximale de 3 nombres entiers a, b et c donnés en entrée :

Procédure MiniMaxi(Entrée a, b, c : entier, Sortie Min, Max : entier)


Début
Si a>b alors
Si a>c alors
Max Åa
Si b>c alors
MinÅc
Sinon
MinÅb
FinSi
Sinon
Max Åc
Min Åb
FinSi
Sinon
Si b>c alors
Max Åb
Si a>c alors
MinÅc
Sinon
MinÅa
FinSi
Sinon
Max Åc
Min Åa
FinSi
FinSi
Fin

¾ Passage de paramètres et appel de procédure au sein d’un algorithme

Lorsqu’on appelle une procédure dans un algorithme, on remplace chaque paramètre formel
par une valeur nommée paramètre effectif ou argument en suivant l’ordre de déclaration des
paramètres formels. On nomme passage de paramètre, l’association de valeur qui est utilisée
entre le paramètre effectif et le paramètre formel.
L'appel d'une procédure représente une instruction à part entière dont la syntaxe est :
NomProcedure(valeur_argument1,valeur_argument2,…,valeur_argumentn)
Où NomProcedure représente le nom de la procédure appelée et valeur_argumenti
correspond au paramètre effectif associé au ième paramètre formel.

¾ REMARQUES :
o Le nombre d'arguments doit correspondre au nombre de paramètres formels.
o Le type du ième argument doit correspondre au type du ième paramètre.
o Le ième argument a, de préférence, un nom différent de celui du ième paramètre.
o Les arguments qui correspondent à des paramètres en entrée peuvent être des
valeurs littérales ou des variables ayant des valeurs au moment de l’appel tandis
que ceux qui correspondent à des paramètres en sortie ou en entrée/sortie doivent
obligatoirement être des variables.
o Un argument omis sera remplacé par sa valeur par défaut dans la procédure.

CYCLE INGENIEUR et DESS INFORMATIQUE p 21/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
¾ Exemple1: Appel de la procédure Somme qui affiche la somme de deux nombres

Algorithme Exemple1
Variables
X, Y : Entier
Début Lors de l’appel d’une procédure, il faut veiller
Afficher ''Entrez le premier nombre'' à fournir des arguments du même type et dans
Saisir X le même ordre que les paramètres de la
Afficher'' Entrez le deuxième nombre '' procédure. Ici, les arguments X et Y de type
Saisir Y entiers remplaceront les paramètres formels A
Somme(X,Y) et B de même type dans la procédure.
Fin

¾ Exemple2: Appel de la procédure MiniMaxi qui retourne le minimum et le


maximum de 3 nombres

Algorithme Exemple2 Dans le cas des paramètres en sortie,


Variables leurs valeurs seront affectées après
X, Y, Z, Minimum, Maximum : entier l’appel de la procédure. Ici Minimum
Début et Maximum contiendront les valeurs
Afficher ''Entrez trois nombres'' minimales et maximales des trois
Saisir(X,Y,Z) nombres à l’appel de la procédure.
MiniMaxi(X,Y,Z, Minimum, Maximum)
Afficher(''Le Minimum vaut'', Minimum, ''Le Maximum vaut'', Maximum)
Fin.

CYCLE INGENIEUR et DESS INFORMATIQUE p 22/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES

5.2 Fonctions, Appel de fonction et Récursivité

¾ Définition et principe d’une fonction

Une fonction est une suite d’instructions considérée comme un sous-algorithme et destinée
à réaliser une ou plusieurs actions, qui retourne obligatoirement et explicitement une valeur
(résultat) à l’algorithme appelant. Elle peut aussi prendre en arguments des paramètres pour les
utiliser dans ses calculs.
Une fonction est une procédure particulière, qui ne génère qu’un et un seul résultat
généralement de type simple : Entier, réel, booléen, caractère.

¾ Syntaxe de déclaration d’une fonction

La déclaration d’une fonction se fait par le mot clé « fonction » suivi du nom de la fonction,
suivi de la déclaration des paramètres formels de la fonction mis entre parenthèses et séparés par
des virgules, suivi du type de la valeur retournée. Ensuite, suit on déclare les variables «locales» de
la fonction puis on place les instructions de la fonction entre début et fin.

Ainsi, voici la syntaxe correspondant à la déclaration d’une fonction :

fonction NomFonction (parametre1:Type1, parametre2:Type2, …) : Type résultat


[Déclaration des variables locales]
DEBUT
Liste des instructions de la fonction
RETOURNER Expression ou Valeur
FIN

¾ Remarques :
o L’instruction RETOURNER permet de renvoyer comme résultat de la fonction la
valeur ou le résultat de l’expression placée à la suite.
o Cette instruction peut aussi être remplacée par une instruction d’affectation de la
valeur du résultat au nom de la fonction : NomFonction Å Expression ou Valeur
o Une fonction retourne obligatoirement une et une seule valeur résultat à l’appelant.
o Ne jamais oublier de préciser le type du résultat dans l’entête de la fonction.

¾ Définition des paramètres formels d’une fonction :

Seul le passage de paramètres en Entrée est autorisé pour les fonctions. Ces paramètres
constituent les données pour la fonction et toutes les modifications effectuées sur ces paramètres
dans la fonction ne seront pas effectives pour le reste de l’algorithme.

¾ Exemple : Fonction permettant de calculer la puissance N d’un nombre X :

Fonction PUISSANCE(X : réel, N : entier) : réel


Variables
I : entier
P: réel
Début
PÅ1
Pour IÅ1 à N Faire
P ÅP*X
Finpour
PUISSANCEÅP (ou encore Retourner P)
Fin

CYCLE INGENIEUR et DESS INFORMATIQUE p 23/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES

¾ Passage de paramètres et appel de fonction au sein d’un algorithme

Le passage de paramètre à une fonction est identique au cas d’une procédure.


Une fonction retourne toujours une information à l’algorithme appelant. C’est pourquoi
l’appel de la fonction doit figurer comme une expression à l'intérieur d'une instruction. On ne peut
donc pas trouver l'appel d'une fonction tout seul, sur une ligne à part. Il se trouve forcément dans
un calcul, une affectation, un affichage, un test, etc.
La syntaxe, dans le cas d’une affectation par exemple, est donc :

NomVariable=NomFonction(valeur_argument1,…,valeur_argumentn)

Où NomVariable représente le nom de la variable qui reçoit le résultat de la fonction,


NomFonction représente le nom de la fonction appelée et valeur_argumenti correspond au
paramètre effectif associé au ième paramètre formel.

En effet, l'appel d'une fonction est remplacé à l'exécution par la valeur qu’elle retourne.

¾ REMARQUES :

o Le nombre d'arguments doit correspondre au nombre de paramètres formels.


o Le type du ième argument doit correspondre au type du ième paramètre.
o Le ième argument a, de préférence, un nom différent de celui du ième paramètre.
o Les arguments peuvent être des valeurs littérales ou des variables ayant des valeurs
au moment de l’appel.
o Un argument omis sera remplacé par sa valeur par défaut dans la fonction.

¾ Exemple: Appel de la fonction PUISSANCE qui calcule la puissance d’un nombre

Algorithme AppelFonction
Variables
A, C : Reel
B : Entier L’appel d’une fonction intervient dans
Début
une instruction dans laquelle le résultat
Afficher ''Entrez le premier nombre''
de la fonction peut être directement
Saisir A
utilisé. Ici, la fonction PUISSANCE est
Afficher '' Entrez la puissance voulue "
Saisir B
appelée dans une instruction d’affectation
C Å PUISSANCE(A,B) et son résultat est affecté à la variable C.
Afficher(A,‘’a la puissance’’,B,’’vaut’’,C)
Fin

¾ Remarque :

Il existe dans tous les langages de programmation des fonctions standard appelées
fonctions prédéfinies du langage. Ces fonctions peuvent être utilisées directement en
programmation sans que l’on ait besoin de les recoder.

CYCLE INGENIEUR et DESS INFORMATIQUE p 24/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES

¾ Récursivité des fonctions : Définition et Principe

Une fonction récursive est une fonction qui s'appelle elle-même. Ce genre de fonction est
utile pour résoudre des problèmes faisant intervenir une suite finie de cas.
Une fonction récursive découpe le problème en morceaux plus petits et s'appelle elle-même
pour résoudre chacun des plus petits morceaux du problème. Les fonctions récursives permettent
de résoudre des problèmes généralement complexes à résoudre avec des fonctions ordinaires.

Il existe deux types de récursivités :

o La récursivité terminale : concerne les fonctions récursives qui algorithmiquement


peuvent être transformées en fonctions non récursives en utilisant des itérations.
o La récursivité non terminale : concerne les fonctions récursives qui ne peuvent
pas être transformées en fonctions non récursives.

Pour écrire une fonction récursive, il faut :

o Définir le cas général : il contiendra l'appel récursif


o Définir le cas particulier : test d'arrêt permettant d’éviter les appels infinis.

Les fonctions récursives sont souvent plus gourmandes en ressources. C’est pourquoi
certaines règles sont à respecter pour mettre en place de telles fonctions.

¾ Règles fondamentales d’une fonction récursive :

o 1- La récursivité doit s'arrêter à un moment donné : Il doit y avoir


obligatoirement dans la fonction récursive, une expression conditionnelle dont au
moins un des cas conduit à un arrêt du fonctionnement récursif de la fonction. Cela
correspond à ce qu’on appelle le chemin non récursif (chemin où la fonction ne
s'appelle pas de nouveau). Si un tel chemin n’existe pas, la fonction tournera sans fin
ou du moins, elle plantera quand la mémoire sera pleine ('StackOverflow').

o 2- Les paramètres d’appel de la fonction ne doivent jamais être les mêmes


que lors de l'appel précédent : Sinon la fonction tournera indéfiniment.

o 3- Le nombre d'appel récursif ne doit pas être très grand : sinon, il pourrait
également survenir un dépassement de la capacité mémoire ('StackOverflow').

o 4- La fonction récursive ne doit pas déclarer un grand nombre de variables


sous peine d'occuper une place trop importante en mémoire.

o 5- Il faut limiter les appels à une seule fonction récursive en même temps
afin d’éviter le phénomène des fonctions récursives imbriquées.

o 6- Chaque fois qu'une fonction est appelée de manière récursive, un ou


plusieurs des arguments qui lui sont transmis doivent se rapprocher de la
condition d'arrêt sinon il n'y aura jamais d'arrêt.

o 7- La complexité du problème doit être réduite à chaque nouvel appel


récursif sinon l’utilisation d’une fonction récursive serait sans intérêt.

CYCLE INGENIEUR et DESS INFORMATIQUE p 25/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
¾ Exemples de fonctions récursives :

o Exemple 1 : Calcul de la factorielle d’un nombre

Pour rappel : N!= N * (N-1) * (N-2).... * 3 * 2 * 1


On remarque donc que : N!= N*(N-1)!
En sachant que 1!=1, créons la fonction en nous appuyant sur la règle suivante :
• Pour N=1 la fonction Factorielle retourne 1,
• Pour les autres cas, elle retourne N * Factorielle(N-1)

Ce qui donne le code suivant en algorithmique :

Fonction Factorielle (N : Entier) : Entier


Début
Si N=1 Alors
Retourner 1
Sinon
Retourner N * Factorielle(N-1)
FinSi
Fin

On voit bien que la fonction Factorielle s’appelle elle-même : c'est une fonction récursive.

o Exemple 2 : Calcul du PGCD de deux nombres en utilisant la récursivité

Rappelez-vous de l’Algorithme d’Euclide que nous avons étudié au chapitre 4 (cf. Page 17).

On se rend compte avec la méthode utilisée que, pour deux nombres entiers positifs et non
nuls M et N, on obtient :

• Dans le cas où M est divisible par N, on a : PGCD(M,N) = N.


• Dans le cas contraire, on a PGCD(M,N) = PGCD(N, M mod N)

Il s’agit donc d’un cas de récursivité. La fonction récursive peut s’écrire ainsi :

Fonction PGCD(M, N : Entiers) : Entier


Début
Si (M Mod N) = 0 alors
Retourner N
Sinon
Retourner PGCD(N, M Mod N)
FinSi
Fin

¾ Remarques générales sur les procédures et les fonctions :

o Si une procédure ou une fonction écrite n'est jamais appelée, elle ne sera jamais
exécutée. Il faut donc l’appeler explicitement au moins une fois.
o Utilisez une fonction pour retourner un résultat si le résultat correspond à une seule
valeur qui doit être communiquée à l’appelant au lieu d'être affiché.
o Utilisez une procédure avec des paramètres en sortie pour retourner un résultat si
plusieurs variables forment le résultat.

CYCLE INGENIEUR et DESS INFORMATIQUE p 26/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
5.3 Portée des variables : variables locales et variables globales

L'endroit où est déclarée une variable est très important car il détermine dans quelles
procédures et fonctions cette variable pourra être utilisée.

¾ Définition du concept de variable locale et variable globale :

Une variable déclarée à l'intérieur d'une procédure ou d’une fonction est appelée variable locale.
Elle n'est utilisable que dans la procédure ou fonction où elle a été déclarée. Ceci est aussi valable
pour l’algorithme principal : une variable déclarée dans l’algorithme principal n'est utilisable que
dans l’algorithme principal et pas dans les autres procédures et fonctions.

Une variable déclarée à l'extérieur de l’algorithme principal et des procédures et fonctions est
appelée variable globale. Elle est commune à l'ensemble des procédures et fonctions et
l’algorithme principal. Elle est donc utilisable partout.

¾ Remarques sur le choix des noms de variable locale et variable globale :

Le même nom de variable peut désigner plusieurs variables locales différentes. En effet,
rien n'interdit que plusieurs procédures et fonctions utilisent le même nom de variable en local. La
valeur d’une variable locale X dans une procédure donnée n'aura pas d'influence sur la valeur de X
dans une autre procédure, car X correspond à deux emplacements de la mémoire distincts.

En revanche, une variable globale n'existe qu'en un seul exemplaire pour toutes les
procédures et fonctions. Ainsi, chaque fois qu'une procédure ou fonction modifie une variable
globale, sa modification sera visible par toutes les autres procédures ou fonctions. Toutes les
procédures et fonctions peuvent utiliser et éventuellement modifier les variables globales.

Mais ne jamais appeler une variable locale par le même nom qu'une variable globale.

¾ Exemple :

//Déclaration des variables globales


Variables Moyenne : réel
A, B : entiers

Fonction CalculMoyenne (X, Y : entiers) : Réel


//Déclaration des variables locales
Variable M : réel
Début
MÅ(X+Y)/2
Retourner M
Fin

Algorithme Principal
Début
// Utilisation des variables globales
Afficher "Saisir deux nombres A et B"
Saisir A, B
Moyenne Å CalculMoyenne(A,B)
Afficher ‘’la moyenne Arithmétique de’’, A, ‘’et’’, B, ‘’vaut’’, Moyenne
Fin

CYCLE INGENIEUR et DESS INFORMATIQUE p 27/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
Chapitre 6 : Tableaux et Tri de données

¾ Généralités sur les tableaux

Un tableau est une structure de données permettant de mémoriser des valeurs de même
type ou de même nature, chacune étant repérée par un ou plusieurs indices indiquant sa position.
Les indices sont des entiers variant entre une valeur minimale et une valeur maximale.
Généralement, un tableau est représenté par un ensemble de cases contenant chacune une valeur.
Ces cases, encore appelées éléments du tableau, sont qualifiées de variables indicées.
A la différence des variables classiques, qui sont déclarées individuellement avec un nom distinct,
les variables indicées constituant le tableau sont implicitement déclarées lors de la déclaration du
tableau. Un tableau constitue donc un ensemble de variables indicées, toutes du même type,
chaque composante étant repérée par ses indices. Chacune de ces variables indicées se comporte
comme une variable classique (celles que nous avons manipulées jusqu'à présent) : on peut saisir
ou afficher sa valeur, utiliser sa valeur dans une expression ou lui affecter une valeur.

En général, on peut déclarer ou utiliser les tableaux de deux manières, en tant que :
o Variables Tableau, pour les tableaux dont les valeurs peuvent changer.
o Constantes Tableau, pour les tableaux dont les valeurs ne peuvent pas changer.

Pour déclarer un tableau, on déclare une variable ou constante unique, dite composite,
possédant un nom et un nombre d'éléments qui représentent la taille du tableau. Ainsi, chaque
élément d’un tableau sera identifié par le nom du tableau suivi des indices entre crochets.

On distingue des tableaux à taille fixe appelés tableaux statiques ainsi que des tableaux
à taille variables appelés tableaux dynamiques.

La dimension d’un tableau, c’est le nombre d’indices permettant de repérer chaque


élément. Les tableaux peuvent être à une dimension (vecteurs), à deux dimensions
(matrices), ou multidimensionnels.

6.1 Tableaux à une dimension (Vecteurs)

Un tableau à une dimension est un tableau dont chaque valeur peut être identifiée par un
seul indice. Un tel tableau est appelé Vecteur et correspond à un ensemble de cases rangées en
ligne et contenant une liste d’éléments du même type.

¾ Déclaration d’un tableau en tant que Variable :

La syntaxe de déclaration d'une variable tableau à une dimension est la suivante :

Identificateur : tableau [indice_min .. indice_max] de type_des_éléments

Où Identificateur est le nom du tableau, indice_min et indice_max sont les valeurs


minimales et maximales des indices du tableau, et type_des_éléments le type des éléments.

En règle générale, l'indice minimum vaut 1 (par défaut en Algo), et la taille du


tableau est égale à la valeur de l'indice maximum. Dans ce cas, il n’est pas nécessaire d’indiquer
l’indice minimum et la déclaration du tableau peut alors être simplifiée ainsi :

Identificateur : tableau [indice_max] de type_des_éléments

Remarque : On peut aussi utiliser un autre indice minimum (par exemple, 0 comme dans
certains langages). Dans ce cas, l'indice maximum sera égal au nombre d'éléments –1.

CYCLE INGENIEUR et DESS INFORMATIQUE p 28/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
¾ Exemple1 : Déclaration d’un tableau à une dimension

o Pour créer un tableau devant contenir 10 notes de valeur réelle :

Variable Notes : tableau [1..10] de Réels


ou encore Variable Notes : tableau [10] de Réels

18 12,5 16 10 08 11 17 14,5 12 15
indices 1(minimum) …. 10(maximum)

Pour désigner un élément, on indique le nom du tableau suivi de l’indice entre crochets.
Ainsi, Notes[3] représente ici le 3ième élément du tableau Notes et vaut 16.

¾ Exemple2 : Utilisation d’un tableau à une dimension

o Procédure permettant de saisir et afficher les éléments du tableau précédant :

Procédure InitialiserNotes(Sortie TablNotes : tableau[10] de réels)


Variable i : entier
Début
Pour iÅ 1 à 10 Faire
Afficher "Saisir la note numéro "+i+"sur 20"
Saisir TablNotes[i]
FinPour
Afficher "Voici la liste de ces notes sur 20"
Pour iÅ1 à 10 Faire
Afficher ‘’la Note numéro ’’+i+’’vaut’’+TablNotes[i]
FinPour
Fin

¾ Déclaration d’un tableau en tant que Constante :

Il est parfois utile de déclarer un tableau en tant que constante, c’est-à-dire un tableau dont
les valeurs ne changent pas. Dans ce cas, comme pour les autres constantes, il faut initialiser les
valeurs du tableau dès la déclaration. Pour cela, on utilise une liste d’initialisation entre accolades.

La syntaxe de déclaration d'une constante tableau à une dimension est donc la suivante :

Identificateur : tableau [indice_min .. indice_max]Å{valeur1, …,valeurn}

Où Identificateur est le nom du tableau, indice_min et indice_max sont les valeurs minimales
et maximales des indices du tableau, et valeur1, valeurn les valeurs des éléments.

De même, si on considère que l'indice minimum vaut 1 (par défaut en Algo), il n’est
pas nécessaire d’indiquer cette valeur et la déclaration du tableau, peut alors être simplifiée ainsi :

Identificateur : tableau [indice_max]Å{valeur1, …,valeurn}

¾ Exemple : Déclaration d’une constante tableau qui mémorise les 12 mois :

TablMois:tableau[1..12]Å{"janvier","février","mars","avril","mai","juin","juillet","aôut",
"septembre","octobre","novembre","décembre"}

CYCLE INGENIEUR et DESS INFORMATIQUE p 29/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
6.2 Tableaux Multidimensionnels

Un tableau multidimensionnel est un tableau dont chaque valeur doit être identifiée par
plusieurs indices. Pour le cas de 2 indices, on parle de tableaux à deux dimensions ou
Matrices. On les représente par une grille dont les cases sont rangées en ligne et en colonne.

¾ Tableaux à deux dimensions (Matrices) :

La syntaxe de déclaration d'un tableau à deux dimensions est la suivante :

Identificateur : tableau [indice1_min .. indice1_max, indice2_min .. indice2_max]


de type_des_éléments

Où Identificateur est le nom du tableau, indice1_min et indice1_max sont les valeurs


minimales et maximales des indices en Ligne du tableau, indice2_min et indice2_max sont les
valeurs minimales et maximales des indices en Colonne du tableau et type_des_éléments le type des
éléments du tableau.

En règle générale, les indices minimum valent 1 (par défaut en Algo), et la taille du
tableau est égale au produit des valeurs des indices maximum. Dans ce cas, il n’est pas
nécessaire d’indiquer les indices minimum et la déclaration peut alors être simplifiée ainsi :

Identificateur : tableau [indice1_max , indice2_max] de type_des_éléments

¾ Exemple1 : Déclaration d’un tableau à deux dimensions

o Pour créer un tableau devant contenir 5 notes par matière pour 3 matières:

Variable Notes2 : tableau [1..3,1..5] de Réels


ou encore Variable Notes2 : tableau [3,5] de Réels

18 12,5 16 10 08
15 13 17 12 18
09 12 14,5 15 13,5
Pour désigner un élément, on indique le nom du tableau suivi des indices entre crochets.
Ainsi, Notes2[3,4] représente ici la 4ème note de la 3ème matière et vaut 15.

¾ Exemple2 : Initialisation d’un tableau à deux dimensions

o Procédure permettant de saisir les éléments du tableau précédant :

Procédure InitialiserNotes2(Sortie TablNotes2 : tableau[3,5] de réels)


Variable i, j : entier
Début
Pour iÅ 1 à 3 Faire
Pour jÅ 1 à 5 Faire
Afficher "Saisir la note numéro"+j+"de la matière"+i
Saisir TablNotes2[i, j]
FinPour
FinPour
Fin

CYCLE INGENIEUR et DESS INFORMATIQUE p 30/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
¾ Tableaux à N dimensions (N>=3) :

La syntaxe de déclaration d'un tableau à n dimensions (N>=3) est la suivante :

Identificateur: tableau[indice1_min.. indice1_max, …, indiceN_min.. indiceN_max]


de type_des_éléments

Où Identificateur est le nom du tableau, indice1_min et indice1_max sont les valeurs


minimales et maximales de la 1ère indice du tableau, indiceN_min et indiceN_max sont les valeurs
minimales et maximales de la Nième indice du tableau et type_des_éléments le type des éléments.

En règle générale, les indices minimum valent 1 (par défaut en Algo), et la taille du
tableau est égale au produit des valeurs des indices maximum. Dans ce cas, il n’est pas
nécessaire d’indiquer les indices minimum et la déclaration peut alors être simplifiée ainsi :

Identificateur : tableau [indice1_max ,…, indiceN_max] de type_des_éléments

Pour désigner les éléments du tableau, la syntaxe obéit à la même règle.


Par exemple, pour désigner l’élément situé aux indices i, j et k dans un tableau T de
dimension 3, on notera T[i,j,k].

¾ Tableaux dynamiques :

Les tableaux que nous venons d’étudier ont une taille prédéfinie à l’avance à travers les
bornes du tableau que sont les indices minimales et maximales : ce sont des tableaux statiques.
Toutefois, il peut arriver que l’on ne connaisse pas à l’avance le nombre d’éléments que
devra comporter un tableau. Certes, une solution consisterait à déclarer un tableau gigantesque.
Mais d’une part, on n’en sera jamais parfaitement sûr, d’autre part, en raison de l’immensité de la
place mémoire réservée et la plupart du temps non utilisée, ce serait un gâchis préjudiciable à la
rapidité, voire à la viabilité de notre algorithme.
Aussi, pour parer à ce genre de situation, a-t-on la possibilité de déclarer un tableau sans
préciser au départ son nombre d’éléments. Ce qui revient à ne pas figer les bornes des indices du
tableau. On parle alors de tableaux dynamiques.
Pour ce genre de tableaux, la taille n’est pas prédéfinie et peut donc varier en cours
d’utilisation. Ainsi, pour modifier dynamiquement la taille d’un tableau après l’avoir déclaré, cela
est possible en Algorithmique grâce à l’instruction Redimensionner notée généralement Redim,
qui permet de redimensionner un tableau afin d’augmenter sa taille.
Pour créer un tableau dynamique, il suffit simplement de ne pas préciser lors de sa
déclaration les bornes minimales et maximales de ses indices. Ainsi, on fur et à mesure qu’on
ajoutera des éléments au tableau dynamique, l’indice correspondant au dernier élément ajouté
sera considéré comme l’indice maximum.
L’accès aux éléments d’un tableau dynamique est identique à celui des tableaux statiques.
Les tableaux dynamiques sont la solution minimisant la place occupée en mémoire pour de
gros ensembles de données car seule la place nécessaire est réservée.

La syntaxe de déclaration d'un tableau dynamique à une dimension est la suivante :

Identificateur : tableau [ ] de type_des_éléments

La syntaxe de déclaration d'un tableau dynamique à deux dimensions est :

Identificateur : tableau [ , ] de type_des_éléments

Pour redimensionner un tableau dynamique, la syntaxe est :


Redim Indentificateur[indiceMax]

CYCLE INGENIEUR et DESS INFORMATIQUE p 31/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES

6.3 Algorithmes de Tri des Tableaux

La plupart du temps, les valeurs contenues dans un tableau sont rangées dans un ordre
quelconque qui ne correspond pas à l’ordre de grandeur exact de ces valeurs. On dit que le tableau
est non trié. Le tri d’un tableau consiste donc à ranger les valeurs du tableau dans le bon ordre de
grandeur, soit de la plus petite à la plus grande valeur (tri dans l’ordre croissant), soit de la plus
grande à plus petite valeur (tri dans l’ordre décroissant).

Selon le dictionnaire, « trier » signifie « répartir en plusieurs classes selon certains


critères ». De manière plus restrictive, le terme de « tri » en algorithmique est très souvent attaché
au processus de classement d'un ensemble d'éléments dans un ordre donné. Par exemple, trier N
entiers dans l'ordre croissant, ou N noms dans l'ordre alphabétique. Tout ensemble muni d'un
ordre total peut fournir une suite d'éléments à trier mais nous étudierons le cas des tableaux.

Il existe plusieurs méthodes classiques de tri des tableaux. A chacune de ces méthodes
correspond généralement un ou plusieurs algorithmes.
Pour décrire plus précisément les différents algorithmes de tri, leur procédure et leur
complexité, nous supposerons dans tout ce qui suit, que l'on dispose d'un tableau à une
dimension de N entiers numérotés de 1 à N et qu'on cherche à trier les entiers dans
l'ordre croissant, c’est-à-dire « de gauche à droite ». Mais, ces algorithmes pourraient
éventuellement aussi s’appliquer à d’autres types de tableaux et vous pourrez aussi les transcrire
aisément dans n’importe quel langage de programmation.

Afin d'évaluer la complexité des différents algorithmes de tri présentés, on comptera le


nombre de comparaisons et d'échanges de valeur entre deux éléments du tableau sans prendre en
compte les affectations et comparaisons sur des variables de comptage de boucles.

On distingue plusieurs algorithmes classiques de Tri de tableau qu’on peut subdiviser en


deux groupes selon la méthode de programmation utilisée :
o Les Algorithmes de Tris itératifs, basés sur des structures itératives
o Les Algorithmes de Tris récursifs, basés sur la récursivité.

¾ Algorithmes de Tri itératifs

Ces algorithmes sont basés sur des méthodes qui trient les éléments du tableau deux à
deux, de manière plus ou moins efficace, mais qui nécessitent toujours de comparer chacun des
N éléments avec chacun des N-1 autres éléments. Le nombre de comparaisons sera donc de
l'ordre de N2 - on note cet ordre de grandeur O(N2). Par exemple, pour N=1000, N2=106, pour
N=106, N2=1012.

Il existe 3 principales méthodes de tris itératifs :


o La méthode de Tri-Bulle ou par propagation : on compare les éléments successifs
du tableau et on les permute si le premier élément est supérieur au second.
o La méthode de Tri par Sélection ou par minimum successif : on parcourt
entièrement le tableau, en recherchant à chaque itération i l’élément qui doit
occuper la ième place.
o La méthode de Tri par Insertion, qui s'apparente au tri de cartes dans un jeu : on
parcourt entièrement le tableau, en recherchant à chaque itération i la place où doit
être positionné le ième élément.

CYCLE INGENIEUR et DESS INFORMATIQUE p 32/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
¾ Le Tri-Bulle ou Tri par propagation

L'algorithme du Tri-Bulle (bubble sort en anglais) ou Tri par propagation consiste à


regarder les différentes valeurs adjacentes d'un tableau T (paire d'éléments consécutifs T[k],
T[k+1]), et à les permuter si le premier des deux éléments est supérieur au second.

L'algorithme se déroule ainsi : les deux premiers éléments du tableau sont comparés, si le
premier élément est supérieur au second, une permutation est effectuée. Ensuite, sont comparés et
éventuellement permutés les valeurs 2 et 3, 3 et 4 jusque (n-1) et n. Une fois cette étape achevée, il
est certain après le premier parcours, que le dernier élément du tableau T[N] est le plus grand. Il
reste donc à appliquer la même procédure sur le tableau composé des éléments T[1] à tab[N-1].
Ainsi, l'algorithme reprend donc pour classer les (n-1) éléments qui précédent. L'algorithme se
termine quand il n'y a plus de permutations possibles.
Pour classer les n valeurs du tableau, il faut effectuer au maximum n itérations. La
complexité de cet algorithme est donc en O(N2), c'est-à-dire du même ordre de grandeur que le
carré du nombre d'éléments.

Cet algorithme porte le nom de tri bulle car, petit à petit, les plus grands éléments du
tableau remontent, par le jeu des permutations, en fin de tableau. Idem dans un aquarium : les
plus grosses bulles remontent plus rapidement à la surface que les petites.

o Version 1 de l’Algorithme : Utilisation de boucles ‘’Pour’’

Procédure TriBulle1(E/S T:tableau[1..N] de Entier)


Variables i, j, temp : Entiers
Début
Pour iÅN à 2 Pasde -1 Faire
Pour jÅ1 à i-1 Faire
Si (T[j] > T[j+1]) Alors
/* permutation des valeurs entre les deux cases successives */
Temp Å T[j]
T[j] Å T[j+1]
T[j+1] Å temp
FinSi
FinPour
FinPour
Fin

o Version 2 de l’Algorithme : Utilisation d’une boucle ‘’Répéter’’

Procédure TriBulle2 (E/S T:tableau[1..N] de Entier)


Variables estTrié : Booléen ; i : Entier
Début
Répéter
estTriéÅVRAI
Pour iÅ1 à N-1 Faire
Si t[i]>T[i+1] Alors
permuter(T[i],T[i+1]) /* voir code permutation ci-dessus */
estTriéÅFAUX
FinSi
FinPour
Jusqua estTrié
Fin

CYCLE INGENIEUR et DESS INFORMATIQUE p 33/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
¾ Le tri par Sélection ou Tri par minimum successif

L'algorithme du Tri par Sélection ou Tri par minimum successif consiste à trouver
dans le tableau l'élément le plus petit, puis à l’échanger avec l’élément à la première place. On
réitère ensuite avec le tableau à partir de la deuxième position, puis avec le tableau à partir de la
troisième position, et ainsi de suite, selon l’illustration suivante :

Le principe de cet algorithme est donc le suivant : Il faut rechercher l’indice (noté min) de
l’élément tel que, quelque soit k, T[k] >= T[min]. Une fois cet indice trouvé, les éléments T[1] et
T[min] sont permutés (on utilisera une variable temporaire de type entier) puis la même procédure
est appliquée sur la suite d'éléments tab[2], ..., tab[N]. Ainsi, chaque élément du tableau sera à sa
place définitive au bout de n-1 itérations. C'est la méthode la plus facile à retenir et à programmer.

o Code de l’Algorithme : Utilisation de deux boucles ‘’Pour’’

Procédure TriSelection(E/S T:tableau[1..N] de Entier)


Variables i, j, min, temp : Entiers
Début
Pour i Å1 à N-1 Pasde -1 Faire
/* recherche de l’indice du minimum */
minÅ i
Pour jÅ i+1 à N Faire
Si (T[j] < T[min]) Alors
minÅj
FinSi
FinPour
/* permutation des valeurs entre la case courante et le minimum */
temp ÅT[i];
T[i] Å T[min];
T[min] Åtemp;
FinPour
Fin

CYCLE INGENIEUR et DESS INFORMATIQUE p 34/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
¾ Le tri par Insertion

L’Algorithme de Tri par Insertion consiste à piocher une à une les valeurs du tableau et à
les insérer, au bon endroit, dans le tableau trié constitué des valeurs précédemment piochées et
triées. Les valeurs sont piochées dans l'ordre où elles apparaissent dans le tableau.

Le principe de cet algorithme est le suivant : soit p l'indice de la valeur piochée, les (p-1)
premières valeurs du tableau constituent le tableau trié dans lequel va être inséré la pième valeur.
Au début de l'algorithme, on considère que la liste constituée du seul premier élément est trié :
c'est vrai puisque cette liste ne comporte qu'un seul élément. Ensuite, on insère le second élément
(p=2), puis le troisième (p=3)... Ainsi, p varie de 2 à n, où n est le nombre d'éléments du tableau.
Cette méthode de tri est très différente de la méthode de tri par sélection et s'apparente à
celle utilisée pour trier ses cartes dans un jeu : on prend une carte, T[1], puis la deuxième, T[2],
que l'on place en fonction de la première, ensuite la troisième T[3] que l'on insère à sa place en
fonction des deux premières et ainsi de suite. Pour placer T[i], on va utiliser une variable
intermédiaire temp pour conserver sa valeur qu'on compare successivement à chaque élément T[i-
1],T[i-2],... qu'on déplace vers la droite tant que sa valeur est supérieure à celle de temp. On affecte
alors à l'emplacement dans le tableau laissé libre par ce décalage la valeur de temp.
Le problème de cet algorithme est qu'il faut parcourir le tableau trié pour savoir à quel
endroit insérer le nouvel élément, puis décaler d'une case toutes les valeurs supérieures à
l'élément à insérer. En pratique, les éléments sont décalés vers la droite tant que l'élément à
insérer est plus petit qu'eux. Dés que l'élément à insérer est plus grand qu'un des éléments du
tableau trié, il n'y a plus de décalage, et l'élément est inséré dans la case laissée vacante par les
éléments qui ont été décalés. Contrairement aux tris par sélection et bulle qui nécessitent un
nombre constant de comparaisons, la complexité du tri par insertion est plus fortement
dépendante de l'ordre du tableau initial le tri par insertion ne conduit qu'à très peu de
comparaisons lorsque le tableau initial est presque en ordre. Ce tri a donc de meilleures propriétés.

o Code de l’Algorithme : Utilisation d’une boucle ‘’Pour’’ et une boucle ‘’TantQue’’

Procédure TriInsertion(E/S T:tableau[1..N] de Entier)


Variables i, j, min, temp : Entiers
Début
Pour iÅ2 à N Faire
tempÅT[i]
jÅ i
TantQue (j > 1 et T[j-1] > temp) Faire
T[j]ÅT[j-1]
jÅj-1
FinTantQue
T[k]Å temp
FinPour
Fin

CYCLE INGENIEUR et DESS INFORMATIQUE p 35/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
¾ Algorithmes de Tri récursifs

Les algorithmes de tris récursifs sont basés sur le principe de la dichotomie (du grec dicho =
deux - tomie = couper) également appelé "diviser pour régner" :

o Diviser : On divise le tableau en deux à chaque étape


o Régner : On trie ces deux tableaux
o Combiner : On combine ces deux tableaux (fusion)

Ce sont des méthodes de tri plus rapides, car elles trient des sous-ensembles d’éléments
puis regroupent les éléments triés. Le nombre de comparaisons est alors de l'ordre de N (log(N)).
Par exemple, pour N=1000, N(log(N))=10000 environ, pour N=106, N(log(N))=20x106 environ.

Il existe 2 principales méthodes de tris récursifs :

o Le Tri Rapide ou Quicksort : l’ingéniosité du tri se trouve au niveau de la division


du tableau (partitionnement)
o Le Tri par Fusion : l’ingéniosité du tri se trouve au niveau la combinaison des deux
tableaux

¾ Le Tri Rapide ou Quicksort

Cette méthode de tri est probablement la plus utilisée actuellement. Elle a été inventée par
Sir Charles Antony Richard Hoare en 1960. Elle illustre le principe dit « diviser pour régner », qui
consiste à appliquer récursivement une méthode destinée à un problème de taille donnée à des
sous-problèmes similaires, mais de taille inférieure. Ce principe général produit des algorithmes
qui permettent souvent d'importantes réductions de complexité.
On considère un élément au hasard dans le tableau appelé le pivot, dont on affecte la
valeur à une variable, disons pivot. On procède alors à une partition du tableau en 2 zones : les
éléments inférieurs ou égaux à pivot et les éléments supérieurs ou égaux à pivot. Si on parvient à
mettre les éléments plus petits en tête du tableau et les éléments plus grands en queue de tableau,
alors on peut placer la valeur de pivot à sa place définitive, entre les deux zones. On répète ensuite
récursivement la procédure sur chacune des partitions créées jusqu'à ce qu'elle soit réduite à un
ensemble à un seul élément.

La partie du tri la plus sensible reste le choix du pivot. Dans la plupart du temps, il est
choisi au hasard parmi les éléments du tableau, mais ce choix peut se révéler catastrophique : si le
pivot est à chaque choix le plus petit élément du tableau, alors le tri rapide dégénère en tri par
sélection. On montre que la complexité de ce tri est :
• dans le meilleur des cas, en O (N log N) ;
• en moyenne, en O (N log N) ;
• dans le pire des cas, en O (N2).
Il existe bon nombre d'astuces pour optimiser le tri rapide, ce qui rend finalement cette
méthode la plus rapide en moyenne parmi toutes celles utilisées.

o Code de l’Algorithme : Utilisation d’une procédure récursive

Procédure triRapide(E/S T:tableau[1..N] de Entier)


/* appel de la procédure récursive */
Début
triRapideRecursif(T[1..N])
Fin

CYCLE INGENIEUR et DESS INFORMATIQUE p 36/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
Procédure triRapideRecursif (E/S tab:tableau[debut..fin] de Entier)
/* code de la procédure récursive */
Variables i, j, min, temp : Entiers
Début
Si (fin > debut) Alors
pivot0 Å Random(N) /* utilisation d’un nombre aléatoire entre 1 et N*/
indicePivot Å partition(Tab[debut..fin], pivot0);
triRapideRecursif (tab[debut..indicePivot–1])
triRapideRecursif (tab[indicePivot +1.. fin]);
Fin
Fin

Fonction partition(tab:tableau[debut..fin] de Entier, indicePivot :Entier) : Entier


/* Code de la fonction partition */
Variables i,k, pivot, temp : Entiers
Début
pivot Å tab[indicePivot];
k Ådebut;
Pour iÅ debut à fin Faire
Si (tab[i] < pivot) Alors
temp Å tab[i];
tab[i] Å tab[k];
tab[k] Å temp;
k Å k + 1;
FinSi
FinPour
tab[k] Å pivot;
RETOURNER k;
Fin

¾ Le Tri par Fusion

Cette méthode de Tri est également basée sur le principe du « diviser pour régner ». En
effet, étant données deux suites d'éléments triés, de longueurs respectives L1 et L2, il est très
facile d'obtenir une troisième suite d'éléments triés de longueur L1 + L2, par fusion des deux
précédentes suites.

Le principe de cette méthode de Tri est le suivant :


o Diviser le tableau en deux sous-tableaux de même longueur (à plus ou moins 1 près)
o Trier le sous-tableau gauche et le sous-tableau droit
o Fusionner les deux sous-tableaux

On constate que la procédure de fusion nécessite un tableau intermédiaire aussi grand que
le nombre d'éléments à interclasser. C'est là où réside le principal inconvénient du tri fusion, car si
sa complexité dans tous les cas est en O (N log N), c'est au prix d'un tableau annexe aussi grand
que le tableau initial, ce qui peut se révéler handicapant dans les situations où la place mémoire
est restreinte.

CYCLE INGENIEUR et DESS INFORMATIQUE p 37/38


© Professeur : ADINGRA Benjamin année académique 2006-2007
SUPPORT DE COURS ALGO et STRUCTURES DES DONNEES
o Code de l’Algorithme : Utilisation d’une procédure récursive

Procédure triFusion(E/S T:tableau[1..N] de Entier)


/* appel de la procédure récursive */
Variables TabTemp : tableau[ ] de Entier
Début
triFusionR(T, TabTemp, 1, N);
Fin

Voici le code la procédure récursive :

Procédure triFusionR(E/S Tab, Temp :tableau[] de Entier, E debut,fin :Entier)


Variables milieu : Entier
Début
Si (debut < fin) Alors
milieu Å (debut + fin)/2;
triFusionR(tab, temp, debut, milieu);
triFusionR(tab, temp, milieu + 1, fin);
fusion(tab, temp, debut, milieu, fin);
FinSi
Fin

Voici la procédure de fusion :

Procédure fusion(E/S Tab, Temp :tableau[] de Entier, E debut, fin :Entier)


Variables i,j,k: Entiers
Début
i Å debut;
j Åmil + 1;
Pour kÅdebut à fin Faire
Si ((j > fin) ou (i <= mil et tab[i] < tab[j])) alors
temp[k] Å tab[i];
i Å i + 1;
Sinon
temp[k] Åtab[j];
j Å j + 1;
FinSi
FinPour
Pour kÅdebut à fin Faire
tab[k] Å temp[k];
FinPour
Fin

CYCLE INGENIEUR et DESS INFORMATIQUE p 38/38


© Professeur : ADINGRA Benjamin année académique 2006-2007

Vous aimerez peut-être aussi