Les éléments de base de l’algorithmique Nga Nguyen - EISTI
Qu’est-ce que l’algorithmique ? … c’est une suite d’instructions, qui une fois exécutée correctement, conduit à un résultat donné. Etape essentielle qui précède la programmation indépendante des particularités de tel ou tel langage pseudo-code origine : nom d’un mathématicien arabe Al Khuwarizmi Matière indispensable pour la formation en informatique
Plan Cours 1 : éléments de base Cours 2 : procédures et fonctions Cours 3 : notions complémentaires : récursivité, complexité, … Cours 4 : structure de données - tableau
Cours 1 : Les éléments de base Variable Expression Affectation Lecture Ecriture Tests Boucles
Les variables stocker provisoirement des valeurs déclaration des variables nom type de codage (entier, réel, booléen, date, caractère, string, …) + taille Cette valeur est contenue dans une case mémoire accessible par son nom
Instruction d’affectation une affectation : variable ← expression quelles seront les valeurs des variables A et B après exécution des instructions suivantes ? Variable A, B : Entier Début A ← 5 B ← 2 A ← B B ← A Fin comment faire pour échanger les valeurs de A et B ? une instruction d’affectation ne modifie que ce qui est situé à gauche de la flèche Moralité : les deux dernières instructions permettent-elles d’échanger les deux valeurs de B et A ? Si l’on inverse les deux dernières instructions, cela change-t-il quelque chose ? Exercice 3. Plus difficile, mais c’est un classique absolu, qu’il faut absolument maîtriser : écrire un algorithme permettant d’échanger les valeurs de deux variables A et B, et ce quel que soit leur contenu préalable. Une variante du précédent : on dispose de trois variables A, B et C. Ecrivez un algorithme transférant à B la valeur de A, à C la valeur de B et à A la valeur de C (toujours quels que soient les contenus préalables de ces variables).
Expressions et opérateurs Une expression est un ensemble de valeurs, reliées par des opérateurs, et équivalent à une seule valeur Opérateurs numériques : +, -, *, /, ^ alphanumériques : & booléens : et, ou, non, xor
Lecture et écriture Lecture : rentrer des valeurs au clavier pour qu’elles soient utilisées par le programme Ecriture : communiquer des valeurs à l’utilisateur en les affichant à l’écran Ecrire "Entrez votre nom : " Lire NomFamille dès que le programme rencontre une instruction Lire, l’exécution s’interrompt, attendant la frappe d’une valeur au clavier
Les tests Si booléen Alors Instructions FinSi Si booléen Alors Instructions 1 Sinon Instructions 2 FinSi
Les tests Expression booléenne : Opérateurs de comparaison : Variable Condition (comparaison) Opérateurs de comparaison : ==, !=, <, >, <=, >= Opérateurs logique : et, ou, non, xor
Exemple Variable m, n : Entier Début Ecrire "Entrez deux nombres : " Lire m, n Si (m > 0 ET n > 0) OU (m < 0 ET n < 0) Alors Ecrire "Leur produit est positif" Sinon Ecrire "Leur produit est négatif" FinSi Fin
Tests imbriqués Variable Temp : Entier Début Ecrire "Entrez la température de l’eau :" Lire Temp Si Temp <= 0 Alors Ecrire "C’est de la glace" Sinon Si Temp < 100 Alors Ecrire "C’est du liquide" Sinon Ecrire "C’est de la vapeur" FinSi FinSi Fin
Les boucles Tantque booléen … Instructions … FinTantque
Exemple : contrôle de saisie Variable Rep : Caractère Début Ecrire "Voulez vous un café ? (O/N)" Lire Rep Tantque Rep <> "O" et Rep <> "N" Lire Rep FinTantque Fin Remarque : si on enlève la 1ère lecture Lire Rep ? => Rep n’est pas initialisée
Une autre structure de boucle Pour Compteur ← Initial à Final Pas ValeurDuPas … Instructions … FinPour
Exemple : calculer la somme 1+2+…+N Variable N, i, Som : Entier Début Ecrire "Entrez un nombre : " Lire N Som ← 0 Pour i ← 1 à N Som ← Som + i FinPour Ecrire "La somme est : ", Som Fin
Cours 2 : Procédures et fonctions Variable globale et locale
Procédure Instructions une suite d’instructions réalisant une certaine tâche, à la quelle on donne un nom pour qu’on puisse l’appeler ultérieurement déclaration : Procédure nom(liste de paramètres) Variables locales Instructions FinProcédure
Exemple Procédure CalculCarrés (debut, fin : ENTIER) Variable nb : ENTIER nb ← debut Tantque nb <= fin Ecrire nb, nb*nb nb ← nb + 1 FinTantque FinProcédure
Appel d’une procédure nom(liste de paramètres effectifs) CalculCarres(1,10) … CalculCarres(20,25)
Fonction Instructions Pour renvoyer une valeur à la procédure / fonction appelante Fonction nom(liste de paramètres) : type de retour Variables locales Instructions Retourner … FinFonction
Exemple Déclaration : Appel : x ← CalculCarré(5) Fonction CalculCarré (nb : ENTIER) : Entier Retourner nb*nb FinFonction Appel : x ← CalculCarré(5)
Fonctions prédéfinies Fonctions de texte : Len(chaîne) : nombre de caractères d’une chaîne Mid(chaîne,n1,n2) : extrait de la chaîne, commençant au caractère n1 et faisant n2 caractères de long. Trouve(chaîne1,chaîne2) : position de chaîne2 dans chaîne1 Ascii(c) Char(n) …
Fonctions prédéfinies Fonctions numériques : Ent(n) : partie entière d’un nombre Mod(n1,n2) : reste de la division de n1 par n2 Alea() : nombre aléatoire … Fonctions de conversion
2 types de paramètres Procédure appelante Procédure appelée Procédure CalculCarre(E nb : Entier, S res : Entier) Paramètres d’entrée Procédure appelante Procédure appelée Paramètres de sortie
2 modes de passage Passage par valeur : Passage par référence : la procédure appelée dispose d'une copie de la valeur; elle peut la modifier, l'information initiale dans l’appelante n'est pas affectée par ces modifications Passage par référence : la procédure appelée modifie directement la variable en utilisant sa référence (adresse mémoire) Procédure Bidule(titi : Caractère par valeur, toto : Caractère par référence) l’appelée ne travaillant que sur une copie de la variable qui a été fournie par l’appelante, elle est incapable de modifier la valeur de celle-ci à partir du moment où une variable est considérée comme un pointeur, toute affectation de cette variable se traduit automatiquement par la modification de la variable sur laquelle elle pointe.
Relation entre type et mode de passage d’argument passage par valeur passage par référence paramètre d’entrée oui paramètre de sortie non
Variable locale et globale Variable locale (privée) : déclarée au sein d'une procédure ou d'une fonction N’est visible que par cette procédure / fonction Variable globale (publique) : une autre possibilité de communiquer entre les procédures Visible par tout le programme
Une application bien programmée ? est une application à l'architecture claire, dont les différents modules font ce qu'ils disent, disent ce qu'il font, et peuvent être testés (ou modifiés) un par un sans perturber le reste de la construction. limiter au minimum l'utilisation des variables globales. regrouper sous forme de modules distincts tous les morceaux de code qui possèdent une certaine unité fonctionnelle faire de ces modules des fonctions lorsqu'ils renvoient un résultat unique, et des sous-procédures dans tous les autres cas
Cours 3 : Notions complémentaires Structures de données Récursif vs itératif Complexité
Structures de données Variable scalaire Tableau Entier, réel, booléen, caractère, string Tableau Structure de donnée linaire Pile : liste où l'insertion et la suppression ne se font que d'un seul et même côté (LIFO) File : liste où l'insertion d'un côté, et la suppression de l'autre (FIFO) Liste : insertions et suppressions se font non seulement aux extrémités, mais aussi à l'intérieur de la liste. Structure de donnée non linaire Arbre Graphe
Récursivité Définition : une fonction/procédure qui s'appelle elle-même Fonction Fact (n : Entier) : Entier Si n = 0 Alors Retourner 1 Sinon Retourner Fact(n-1) * n FinSi FinFonction
Version itérative Fonction Fact (n : Entier) : Entier Variable f, i : Entier f ← 1 Pour i ← 2 à n f ← f*i FinPour Retourner f FinFonction
Avantages vs inconvénients très économique pour le programmeur : simple et intuitive très dispendieuse de ressources machine : utilisation de pile tout problème formulé en termes récursifs peut également être formulé en termes itératifs !
Complexité Un ’bon’ algorithme ? La performance d’un algorithme Répond correctement au problème posé Rapide (complexité en temps) Pas trop de mémoire (complexité en espace) La performance d’un algorithme Taille, structure de donnée d’entrée Nombre d’opérations élémentaires opérations arithmétiques affectations instructions de contrôle etc.
Pire cas, meilleur cas et moyenne La complexité dans le “pire cas” : Max C(d) d donnée de taille n où C(d) est le nombre d’opérations élémentaires pour exécuter l’algorithme sur la donnée d’entrée d La complexité dans le “meilleur cas” : Min C(d) La complexité en moyenne : ∑ ∏(d)C(d) où ∏(d) est la probabilité d’avoir en entrée une instance d parmi toutes les données de taille n
Notation asymptotique Soient f, g : Nat -> Nat f(n) = O(g(n)) ssi il existe 2 constantes positives n0 et B t.q n ≥ n0, f(n) ≤ Bg(n) Un algorithme en O(1) : complexité constante O(n) : complexité linaire O(na) : complexité polynomiale O(en) : complexité exponentielle …
Exemple 1 : le plus petit élément int plusPetit (int[] x) { int k = 0; int n = length(x); for (int i = 1; i < n; i++) { if (x[i] < x[k]) k = i; } return k; Au pire cas : nombre d’affectations : 2 + n + (n-1) nombre de comparaisons : n + (n-1) complexité : O(n) En moyenne ?
Exemple 2 : factorielle Fonction Fact (n : Entier) : Entier Si n = 0 Alors Retourner 1 Sinon Retourner Fact(n-1) * n FinSi FinFonction C(n) : nombre de comparaisons C(n) = 1 + C(n-1) C(0) = 1 => complexité : O(n)
Exemple 3 : Tours de Hanoi
Tours de Hanoi (suite) Procédure Déplacer (nombre : Entier, de : Entier, à : Entier, par : Entier) Si nombre > 0 Alors Déplacer (nombre-1, de, par, à); Bouger-un-disque de, à; Déplacer (nombre-1, par, à, de); FinSi FinProcédure C(n) : nombre de déplacements C(n+1) = 2C(n) + 1 => exponentielle
Cours 4 : Tableaux Structure de données Algorithmes de recherche : Séquentielle Dichotomique Algorithmes de tri : Tri par sélection Tri à bulles
Tableaux But : regrouper dans une structure plusieurs valeurs de même type Déclaration : A[n] : Tableau de T nom du tableau : A taille de tableau : n type d’élément : T indice : A[i], 1 ≤ i≤ n Exemple : Mois[12] : Tableau de Caractère Mois = {"janvier", "février", …, "décembre"} Mois[5] = "mai" Différences entre tableau et liste !!! Utilisez plutôt le mot Tableau au lieu de Vecteur (en référence à Java)!
Recherche séquentielle Fonction RechSeq (A : Tableau de T, n : Entier, val : T) : Booléen Variable i : Entier, trouve : Booléen i ← 1 trouve ← faux Tantque (i ≤n) ET (NOT trouve) Si A[i] = val Alors trouve ← vrai Sinon i ← i+1 FinSi FinTantque Retouner trouve FinFonction
Recherche séquentielle : complexité Pire cas : nombre de comparaisons : n complexité : O(n) Moyenne : p : probabilité que val soit dans A places équiprobables complexité : ∑pii + (1-p)n = p(n+1)/2 + (1-p)n
Recherche dichotomique Fonction RechDic (A:Tableau de T, min:Entier, max:Entier, val:T) : Booléen Variable mid : Entier, Si (min > max) Alors Retourner faux Sinon mid = (min + max) /2 Si (A[mid] == val) Alors Retourner vrai Si (A[mid] > val) Alors Retourner RechDic(A,mid+1, max, val) Retourner RechDic(A,min, mid-1, val) FinSi FinFonction
Recherche dichotomique : complexité Tableau A est trié ! RechDic(A,0,n,val) C(n) : nombre de comparaisons C(n) = 1 + C(n/2) C(1) = 1 => C(n) = O(logn)
Algorithmes de tri Versions lentes : O(n2) Versions rapides :O(nlogn) Tri par sélection Tri à bulles Tri par insertion Tri de shell (shell sort) … Versions rapides :O(nlogn) Tri rapide (quick sort) Tri fusion (merge sort) Tri pas tas (heap sort)
Tri par sélection Technique : à chaque étape, on met en bonne position l’élément le plus petit. Exemple : 27 | 63 | 1 | 72 | 64 | 58 | 14 | 9 1 | 63 | 27 | 72 | 64 | 58 | 14 | 9 1 | 9 | 27 | 72 | 64 | 58 | 14 | 63 1 | 9 | 14 | 72 | 64 | 58 | 27 | 63
Tri par sélection : algorithme Procédure TriSelection(ES A : Tableau de T, n : Entier) Variable i, j : Entier, temp : T Pour i ← 1 à n-1 posmin ← i Pour j ← i + 1 à n Si T[j] < T[posmin] Alors posmin ← j FinSi FinPour Si posmin ≠ i Alors temp ← T[posmin] T[posmin] ← T[i] T[i] ← temp FinSi FinPour FinProcédure Boucle principale : prenons comme point de départ le premier élément, puis le second, etc, jusqu’à l’avant dernier. Boucle secondaire : à partir de ce point de départ mouvant, recherchons jusqu’à la fin du tableau quel et le plus petit élément. Une fois que nous l’avons trouvé, nous l’échangeons avec le point de départ.
Tri par sélection : complexité Meilleur cas (le tableau est déjà trié) : Nombre de comparaisons : (n-1)+(n-2)+…+1 = n(n-1)/2 Nombre d’échanges : 0 Complexité : O(n²) Pire cas (le tableau est trié en ordre inverse) : Nombre de comparaisons : n(n-1)/2 Nombre d’échanges : n-1 Moyenne : O(n²) Nombre de comparaisons : quand il reste p éléments à traiter, on fait (p-1) comparaisons avec les éléments restants : n
Tri à bulles Principe : Exemple : tout élément est plus petit que celui qui le suit compare chaque élément avec l’élément qui le suit. Si l’ordre n’est pas bon, on permute ces deux éléments. Et on recommence jusqu’à ce que l’on n’ait plus aucune permutation à effectuer Exemple : 27 | 63 | 1 | 72 | 64 | 58 | 14 | 9 27 | 1 | 63 | 64 | 58 | 14 | 9 | 72 1 | 27 | 63 | 58 | 14 | 9 | 64 | 72
Tri à bulles : algorithme Procédure TriBulle(ES A : Tableau de T, n : Entier) Variable desordre : Booléen, i : Entier, temp : T desordre ← vrai Tantque desordre desordre ← faux Pour i ← 1 à n-1 Si A[i] > A[i+1] Alors temp ← A[i] A[i] ← A[i+1] A[i+1] ← temp desordre ← vrai FinSi FinPour FinTantQue FinProcédure
Tri à bulles : complexité Meilleur cas (le tableau est déjà trié) : Nombre de comparaisons : n-1 Nombre d’échanges : 0 Complexité : O(n) Pire cas (le tableau est trié en ordre inverse) : Nombre de comparaisons : O(n²) Nombre d’échanges : O(n²) Complexité : O(n²) Moyenne : O(n²)
Comparaisons des algorithmes de tri (lents)
Comparaisons des algorithmes de tri (rapides)