Cours d'Algorithmique et Programmation 2025
Cours d'Algorithmique et Programmation 2025
ET PROGRAMMATION
ENSET 2025
Initiation à l’algorithmique :
Introduction
L’algorithmique constitue une pierre angulaire de l’ingénierie moderne, offrant des outils et des
méthodes pour analyser et résoudre efficacement des problèmes complexes. Ce cours
d’Initiation à l’algorithmique vise à doter les apprenants des compétences nécessaires pour
adopter une approche structurée dans la modélisation et la résolution de problèmes en
ingénierie.
Objectif général
L’objectif principal de cette unité d’enseignement (UE) est de permettre aux apprenants de
développer une démarche analytique rigoureuse pour décomposer les problèmes d’ingénierie
en tâches élémentaires et les résoudre à l’aide de méthodes algorithmiques.
Objectifs spécifiques
Contenu du cours
Le programme de l’UE est structuré pour fournir une compréhension approfondie des concepts
fondamentaux de l’algorithmique tout en mettant l’accent sur leur application pratique. Il
comprend :
1. Les notions de base, telles que les variables et les structures fondamentales en
algorithmique ;
2. La conception et l’utilisation de fonctions et procédures pour structurer les solutions ;
3. La construction d’algorithmes simples pour résoudre des problèmes courants,
notamment le tri et la gestion des données ;
4. L’analyse de la complexité algorithmique pour évaluer la performance des algorithmes
;
5. Des techniques avancées, notamment la récursivité et l’approche "divide and conquer",
essentielles pour résoudre des problèmes de grande envergure.
Ce cours pose les bases indispensables pour aborder des problématiques plus complexes en
ingénierie, tout en développant chez les apprenants une rigueur intellectuelle et des
compétences en résolution algorithmique.
La notion de variables en algorithme est centrale pour la conception et l'optimisation des
programmes informatiques. Les variables jouent divers rôles, allant de la sélection et de
l'optimisation à l'amélioration de l'efficacité des algorithmes.
Définition : Une variable est un espace mémoire identifié par un nom, qui contient une valeur
pouvant être modifiée au cours du temps.
Exemple : Dans un algorithme qui calcule la somme de deux nombres, les nombres et leur
somme peuvent être stockés dans des variables nommées nombre1, nombre2 et somme.
Dans de nombreux langages d’algorithmes et de programmation, une variable doit être déclarée
avant d’être utilisée.
Exemple :
entier x
caractère lettre
boolean estVrai
Initialisation : Attribue une valeur initiale à la variable au moment de sa déclaration ou
plus tard dans l’algorithme.
Exemple :
x ← 10
lettre ← 'A'
estVrai ← vrai
4. Manipulation des Variables
Une variable peut être modifiée, lue ou utilisée dans des calculs et des opérations.
Exemple :
afficher x
Exemple :
x←x+5
Utilisation dans une expression : Les variables peuvent être combinées avec des
opérateurs pour effectuer des calculs.
Exemple :
somme ← x + y
5. Bonnes Pratiques dans l'Utilisation des Variables
Noms significatifs : Utilisez des noms explicites qui reflètent le rôle de la variable.
Exemple : age, salaire.
Respect des types : Assurez-vous que les valeurs attribuées à une variable
correspondent à son type.
Initialisation : Toujours initialiser une variable avant de l’utiliser pour éviter des
comportements imprévisibles.
Documentation : Commentez les variables complexes pour expliquer leur utilité.
Voici un exemple simple illustrant l'utilisation des variables dans un algorithme qui calcule la
somme de deux nombres donnés par l'utilisateur :
Enoncé : Ecrire un algorithme qui lit deux nombres, calcule leur somme et affiche le résultat.
Algorithme :
Début
entier nombre1, nombre2, somme
afficher "Entrez le premier nombre :"
lire nombre1
afficher "Entrez le second nombre :"
lire nombre2
somme ← nombre1 + nombre2
afficher "La somme est :", somme
Fin
7. Erreurs Courantes avec les Variables
8. Exercices Pratiques
1. Déclarez une variable pour chaque type suivant et attribuez-lui une valeur : entier, réel,
chaîne, et booléen.
2. Écrivez un algorithme qui calcule la moyenne de trois nombres donnés par l’utilisateur.
3. Réalisez un algorithme qui échange les valeurs de deux variables.
Cours : Les Structures de Base en Algorithmique
1. La séquence
2. La condition (ou sélection)
3. La boucle (ou itération)
2. La Séquence
Définition : La séquence est l’exécution linéaire d’instructions dans l’ordre dans lequel elles
apparaissent. Chaque instruction est exécutée une fois, de haut en bas.
Début
lire longueur
lire largeur
aire ← longueur × largeur
afficher "L’aire est :", aire
Fin
Description : Les instructions sont exécutées successivement : lecture des dimensions, calcul
de l’aire, puis affichage du résultat.
Définition : La condition permet de choisir une action à effectuer parmi plusieurs possibilités,
en fonction d’un test logique (vrai ou faux).
Syntaxe Générale :
Si...Alors...Sinon :
Si condition Alors
instructions_si_vrai
Sinon
instructions_si_faux
Fin Si
Cas Multiples :
Selon variable Faire
Cas valeur1 : instructions1
Cas valeur2 : instructions2
Autre : instructions_defaut
Fin Selon
Début
lire nombre
Si nombre mod 2 = 0 Alors
afficher "Le nombre est pair"
Sinon
afficher "Le nombre est impair"
Fin Si
Fin
Début
lire chiffre
Selon chiffre Faire
Cas 1 : afficher "Lundi"
Cas 2 : afficher "Mardi"
Cas 3 : afficher "Mercredi"
Cas 4 : afficher "Jeudi"
Cas 5 : afficher "Vendredi"
Cas 6 : afficher "Samedi"
Cas 7 : afficher "Dimanche"
Autre : afficher "Entrée invalide"
Fin Selon
Fin
Définition : La boucle permet de répéter un ensemble d’instructions tant qu’une condition est
vraie ou pour un nombre défini d’itérations.
Types de Boucles :
Enoncé : Ecrire un algorithme qui calcule la somme des nombres pairs entre 1 et 10.
Algorithme :
Début
somme ← 0
Pour i ← 1 à 10 Faire
Si i mod 2 = 0 Alors
somme ← somme + i
Fin Si
Fin Pour
afficher "La somme des nombres pairs est :", somme
Fin
7. Exercices Pratiques
Les fonctions et procédures sont des blocs d’instructions qui permettent de structurer et de
réutiliser le code dans un algorithme. Elles sont essentielles pour simplifier, organiser et
modulariser un programme.
Procédures : Utilisées pour effectuer une action ou une suite d’actions. Elles ne retournent
pas de valeur.
Fonctions : Similaires aux procédures, mais elles retournent une valeur à la fin de leur
exécution.
3. Déclaration et Utilisation
3.1. Déclaration d’une Fonction
Une fonction est déclarée avec un nom, des paramètres (optionnels), un type de retour et un
bloc d’instructions.
Syntaxe :
Une procédure est déclarée avec un nom, des paramètres (optionnels), et un bloc
d’instructions.
Syntaxe :
procédure nom_procédure(paramètres)
instructions
fin procédure
procédure afficher_bienvenue()
afficher "Bienvenue dans ce programme"
fin procédure
3.3. Appel d’une Fonction ou Procédure
Pour une fonction, l’appel se fait dans une expression, par exemple :
x ← carre(5)
afficher_bienvenue()
---
**Exemple :**
---
**Algorithme :**
Début entier l, L, surface afficher "Entrez la longueur :" lire l afficher "Entrez la largeur :" lire
L surface ← calcul_surface(l, L) afficher "La surface est :", surface calcul_perimetre(l, L) Fin
---
---
---
Un algorithme simple est une suite finie et ordonnée d’instructions destinée à résoudre un
problème basique ou à exécuter une tâche précise. Ces algorithmes constituent la base de
toute démarche algorithmique et permettent d’acquérir les fondamentaux avant de passer à
des problèmes plus complexes.
Exemples d’applications :
Exemple général :
Début
Instruction 1
Instruction 2
...
Fin
3. Opérations Fondamentales
1. Lecture et Affichage :
o Permet de recevoir des entrées utilisateur et d’afficher les résultats.
o Exemple :
o afficher "Entrez un nombre :"
o lire nombre
2. Calculs :
o Réalisation d’opérations arithmétiques (addition, multiplication, etc.).
o Exemple :
o somme ← nombre1 + nombre2
3. Conditions :
o Exécution conditionnelle selon des critères.
o Exemple :
o si nombre > 0 alors
o afficher "Le nombre est positif"
o fin si
4. Boucles :
o Répétition d’instructions un certain nombre de fois ou jusqu’à une condition.
o Exemple :
o pour i de 1 à 10 faire
o afficher i
o fin pour
Enoncé : Ecrire un algorithme qui lit deux nombres, calcule leur somme et affiche le résultat.
Algorithme :
Début
entier nombre1, nombre2, somme
afficher "Entrez le premier nombre :"
lire nombre1
afficher "Entrez le second nombre :"
lire nombre2
somme ← nombre1 + nombre2
afficher "La somme est :", somme
Fin
4.2. Maximum de Deux Nombres
Enoncé : Ecrire un algorithme qui détermine le plus grand de deux nombres donnés par
l’utilisateur.
Algorithme :
Début
entier a, b
afficher "Entrez le premier nombre :"
lire a
afficher "Entrez le second nombre :"
lire b
si a > b alors
afficher "Le maximum est :", a
sinon
afficher "Le maximum est :", b
fin si
Fin
4.3. Calcul du Factoriel
Enoncé : Ecrire un algorithme qui calcule le factoriel d’un nombre entier positif donné par
l’utilisateur.
Algorithme :
Début
entier n, factoriel, i
afficher "Entrez un nombre :"
lire n
factoriel ← 1
pour i de 1 à n faire
factoriel ← factoriel × i
fin pour
afficher "Le factoriel de", n, "est :", factoriel
Fin
6. Exercices Pratiques
Le tri est une opération fondamentale en algorithmique. Il consiste à réorganiser les éléments
d’une liste ou d’un tableau selon un ordre prédéfini (croissant, décroissant ou selon des
critères spécifiques).
Complexité temporelle : Temps d’exécution en fonction de la taille des données (O(n), O(n²),
etc.).
Stabilité : Maintien de l’ordre relatif des éléments égaux.
Efficacité mémoire : Quantité de mémoire supplémentaire nécessaire.
Voici quelques algorithmes de tri classiques classés selon leur complexité et leur mode de
fonctionnement :
Principe :
Insère chaque élément de la liste à sa position correcte dans une partie déjà triée.
Complexité :
Exemple :
Début
pour i de 2 à longueur(liste) faire
x ← liste[i]
j ← i - 1
tant que j > 0 et liste[j] > x faire
liste[j+1] ← liste[j]
j ← j - 1
fin tant que
liste[j+1] ← x
fin pour
Fin
3.2. Tri par Sélection
Principe :
Trouve le plus petit élément de la liste et l’échange avec le premier, puis répète pour les
sous-listes restantes.
Complexité :
Exemple :
Début
pour i de 1 à longueur(liste) - 1 faire
min ← i
pour j de i+1 à longueur(liste) faire
si liste[j] < liste[min] alors
min ← j
fin si
fin pour
échanger liste[i] et liste[min]
fin pour
Fin
3.3. Tri à Bulles (Bubble Sort)
Principe :
Compare les éléments adjacents et les échange si nécessaire. Répète jusqu’à ce que la liste
soit triée.
Complexité :
Exemple :
Début
pour i de 1 à longueur(liste) - 1 faire
pour j de 1 à longueur(liste) - i faire
si liste[j] > liste[j+1] alors
échanger liste[j] et liste[j+1]
fin si
fin pour
fin pour
Fin
3.4. Tri Rapide (Quick Sort)
Principe :
Divise pour régner. Sélectionne un pivot, partitionne la liste en deux (les éléments inférieurs
et supérieurs au pivot), puis trie récursivement.
Complexité :
Exemple :
Fonction quickSort(liste)
si longueur(liste) ≤ 1 alors
retourner liste
sinon
pivot ← liste[1]
gauche ← [x pour x dans liste si x < pivot]
droite ← [x pour x dans liste si x > pivot]
retourner quickSort(gauche) + [pivot] + quickSort(droite)
Fin
3.5. Tri par Fusion (Merge Sort)
Principe :
Divise la liste en deux moitiés, trie chacune récursivement, puis fusionne les moitiés triées.
Complexité :
Exemple :
Fonction mergeSort(liste)
si longueur(liste) ≤ 1 alors
retourner liste
sinon
milieu ← longueur(liste) // 2
gauche ← mergeSort(liste[1 à milieu])
droite ← mergeSort(liste[milieu+1 à fin])
retourner fusion(gauche, droite)
Fin
5. Exercices Pratiques
1. Implémentez un algorithme de tri par sélection pour trier une liste de 10 éléments.
2. Réalisez un algorithme de tri rapide pour trier un tableau d’entiers donné par l’utilisateur.
3. Comparez le temps d’exécution entre le tri par insertion et le tri à bulles pour un tableau de
100 éléments aléatoires.
4. Implémentez une version modifiée du tri par fusion pour trier des chaînes de caractères.
Cours : Analyse de la Complexité Algorithmique
Objectifs :
2. Types de Complexité
a) Complexité temporelle
b) Complexité spatiale
Elle évalue la quantité de mémoire requise par l'algorithme, y compris les données d'entrée et
les structures auxiliaires utilisées.
Exemple : Un algorithme de tri par insertion utilise un espace constant en plus des données
d'entrée.
3. Notations Asymptotiques
Tri par insertion : Simple, mais inefficace pour de grandes données (O(n²)).
Tri fusion : Plus adapté aux grandes données (O(n log n)).
Algorithme :
Début
somme ← 0
Pour chaque élément e dans le tableau faire
somme ← somme + e
FinPour
Fin
Algorithme :
Début
max ← tableau[0]
Pour chaque élément e dans le tableau faire
Si e > max alors
max ← e
FinSi
FinPour
Fin
Nombre d'opérations : Une comparaison par élément → O(n).
Complexité spatiale : Une seule variable auxiliaire (‘max’) → O(1).
8. Exercices Pratiques
9. Conclusion
Le paradigme "Divide and Conquer" (Diviser pour Régner) est une stratégie algorithmique
puissante qui consiste à résoudre un problème en le décomposant en sous-problèmes plus
petits, à résoudre ces sous-problèmes, puis à combiner leurs solutions pour obtenir la solution
globale.
Étapes principales :
2. Avantages et Limites
Avantages :
Permet de concevoir des algorithmes efficaces, notamment pour les grands problèmes.
Exploite la récursivité, ce qui rend certains algorithmes plus naturels à concevoir et à
comprendre.
Bien adapté aux architectures parallèles.
Limites :
Principe :
Complexité :
Algorithme :
Début
Si la taille du tableau ≤ 1 alors
retourner le tableau
FinSi
Diviser le tableau en deux moitiés : gauche et droite
Trier récursivement la moitié gauche et la moitié droite
Fusionner les deux moitiés triées
Fin
b) Recherche Binaire
Principe :
Complexité :
Temps : O(log n)
Espace : O(1) ou O(log n) avec une implémentation récursive.
Algorithme :
Début
Si la liste est vide alors
retourner "Non trouvé"
FinSi
Milieu ← indice du milieu de la liste
Si l'élément du milieu = valeur recherchée alors
retourner "Trouvé"
Sinon Si l'élément du milieu > valeur recherchée alors
Rechercher récursivement dans la moitié gauche
Sinon
Rechercher récursivement dans la moitié droite
FinSi
Fin
c) Algorithme de Strassen pour la Multiplication de Matrices
Principe :
Complexité :
Temps : O(n⁸⁺···⁶)
Espace : Dépend de la taille de la mémoire auxiliaire utilisée.
4. Analyse de Complexité
L'efficacité des algorithmes "Divide and Conquer" peut souvent être évaluée en utilisant une
relation de récurrence.
a : Nombre de sous-problèmes.
b : Facteur de réduction de la taille des sous-problèmes.
d : Coût de la division et de la combinaison.
a = 2, b = 2, d = 1
Solution : T(n) = O(n log n)
6. Exercices Pratiques
7. Conclusion
Les algorithmes "Divide and Conquer" exploitent une approche modulaire et récursive pour
résoudre des problèmes complexes de manière efficace. Leur maîtrise est essentielle pour
aborder des problématiques avancées en algorithmique et en ingénierie des systèmes.
Cours : Récursivité en Algorithmique
1. Introduction à la Récursivité
La récursivité est une approche algorithmique où une fonction ou un algorithme s’appelle lui-
même directement ou indirectement. Elle permet de résoudre des problèmes complexes en les
décomposant en sous-problèmes similaires mais plus simples.
Définition : Un algorithme est dit récursif lorsqu’il contient une ou plusieurs instructions qui
mènent à son propre appel.
n! = n × (n-1)! si n > 0
n! = 1 si n = 0
Algorithme :
1. Récursivité directe :
o Une fonction s’appelle directement elle-même.
o Exemple : La factorielle vue précédemment.
2. Récursivité indirecte :
o Une fonction A appelle une fonction B, qui à son tour appelle la fonction A.
3. Récursivité terminale :
o L’appel récursif est la dernière instruction de la fonction.
o Exemple : Calcul de la somme des n premiers nombres naturels.
Algorithme :
Avantages :
Simplifie la conception des algorithmes pour certains problèmes comme les parcours
d’arbres ou les problèmes de type "Divide and Conquer".
Réduit la complexité du code dans des cas où une solution itérative serait plus complexe.
Inconvénients :
6. Applications de la Récursivité
Simplicité Plus lisible pour certains problèmes Peut être complexe pour certains cas
8. Exercices Pratiques
1. Écrire un algorithme récursif pour calculer la somme des n premiers nombres naturels.
2. Implémenter un algorithme récursif pour vérifier si une chaîne de caractères est un
palindrome.
3. Élaborer un algorithme récursif pour parcourir un arbre en profondeur.
4. Comparer les temps d’exécution de l’algorithme de la factorielle en récursif et en itératif.
9. Conclusion
La récursivité est un outil puissant en algorithmique, utile pour décomposer et résoudre des
problèmes complexes. Cependant, elle doit être utilisée avec prudence, en évaluant ses
implications sur la mémoire et la performance. Sa compréhension approfondie est essentielle
pour tout programmeur ou analyste en algorithmique.
Cours : Complexité Algorithmique
2. Types de Complexité
3. Notations Asymptotiques
1. Mesurer les Opérations Dominantes : Identifier les instructions principales qui influencent le
temps d'exécution.
2. Calculer la Fréquence d'Exécution : Compter le nombre de fois qu'une instruction est
exécutée en fonction de la taille de l'entrée.
3. Utiliser les Notations Asymptotiques : Exprimer le résultat en termes de O, Θ ou Ω.
Exemple : Recherche linéaire
Algorithme :
Début
Pour chaque élément de la liste
Si l'élément correspond à la valeur recherchée
Retourner l'indice
FinPour
Fin
Analyse :
6. Cas Pratiques
7. Exercices
8. Conclusion
L'analyse de la complexité algorithmique est un outil essentiel pour déterminer l'efficacité d'un
algorithme. En comprenant les notations asymptotiques et les principes sous-jacents, on peut
conçoitre des solutions plus optimales pour les problèmes complexes. La maîtrise de ce
domaine est indispensable pour tout informaticien ou ingénieur logiciel.