Chapitre III. Algorithmique élémentaire des tableaux (recherche, tri) Définition Recherche séquentielle Recherche dichotomique Tri (insertion, sélection, à bulles, fusion, Dijkstra) Utilisation des tableaux de nombres : histogrammes, matrices
Définition des tableaux Tableau : collection d’objets de même type Type Element = Enregistrement Debut clé : entier; inf1 : chaîne de caractères; inf2 : réel; …. Fin Enregistrement; Var Tab[1..N] Tableau des Element; Problèmes : Recherche des éléments (par clé) Tri (une relation d’ordre est définie sur l’ensemble des clés)
Recherche séquentielle La recherche ne porte que sur la valeur de la clé – « recherche associative » Lorsqu'on recherche une clé qui est présente on parle de recherche positive (variétés des algorithmes : plusieurs occurrences, - première, dernière, toutes) S’il n’existe pas de solution, la recherche se termine sur un échec et ne rend pas de résultat. On parle de recherche négative
Recherche séquentielle dans un tableau non trié (1) Var L: tableau[1…n] des entiers X: entier j: entier Début j:=1 TQ (j<=n et L[j]!=X) faire j:=j+1; FTQ Si j>n alors j:=0 Fsi Complexité Moy?
Recherche séquentielle dans un tableau non trié (2) Opération fondamentale : comparaison Probabilités qu’un élément se trouve à la ième place : Probabilité qu’un élément ne se trouve pas dans le tableau : Coût moyen (nombre de comparaisons)
Recherche séquentielle dans un tableau non trié (3) Recherche positive (on sait que la clé recherchée se trouve dans le tableau), places équiprobables : Coût moyen minimal : Si lorsque les éléments les plus recherchés sont au début du tableau Si plusieurs recherches, il est possible de faire évoluer le tableau de sorte que les éléments les plus recherchés se trouvent au début – recherche autoadaptative M1. Après chaque recherche, placer l’élément recherché en tête (début) M2. Faire progresser l’élément recherchée d’une place vers le début. M1 est meilleure pour les listes chaînées, M2 pour les tableaux.
Recherche séquentielle dans un tableau trié (1) (1) Dénotons probabilités que l’élément recherché X se trouve à la i-ème place (2) Probabilités que X soit strictement compris entre j-ème et j+1-ème, j=1,..,n-1 Probabilités que X soit strictement inférieur (resp. supérieur) au premier (resp. au dernier) (3)
Recherche séquentielle dans un tableau trié(2) Cas particulier : recherche positive (pj=0), toutes les places sont équiprobables (qj=1/n) : Comme c’est le cas de recherche dans un tableau non-trié Complexité
Recherche dichotomique Recherche d’un élément X dans un tableau trié (on supposera l’ordre croissant) Principe : comparer avec l’élément du milieu m du tableau (tab[m]) Si X=tab[m] , la solution est trouvée, arrêt Si X>tab[m], il est impossible que X se trouve avant m dans le tableau et il ne reste à traiter que la moitié droite du tableau Si X<tab[m], X ne peut se trouver que dans la moitié gauche du tableau. On continue ainsi la recherche, en diminuant de moitié le nombre d’éléments de la liste restant à traiter, après chaque comparaison , et si on recherche X dans un tableau ne contenant aucun élément, la recherche se termine sur un échec : X n’est pas dans le tableau. Illustration graphique
Recherche dichotomique. Version récursive Procédure dichot(val X : élément; tab : tableau[1..n] des entiers, g,d : entiers, ref res : entier) {cette procédure renvoie soit l’indice de X dans le tableau soit 0. A l’appel g=1 et d=n} var m : entier Début Si g<d alors m:=(g+d)/2 {division entière} Si X=tab[m] alors res:=m sinon Si X<tab[m] alors dichot(X,tab,g,m-1,res) sinon dichot(X,tab,m+1,d,res) FinSi sinon res:=0 Fin dichot
Version récursive. Eléments d’analyse Une procédure(fonction) récursive s’appelle récursive terminale si il n’y a aucun traitement à exécuter après chacun des appels à elle-même qu’elle contient Transformation en version itérative Procédure P(U) Debut Si C alors traite; P(a(U)); sinon Terminaison; Fin P Procédure P(V) Var U; Tant que C faire U=a(U); FinTq
Version Récursive. Complexité Opération fondamentale : comparaison L’itération atteint 1 quand donc i = (ou dépasse) Ainsi : la recherche dichotomique représente une amélioration importante par rapport à la recherche séquentielle
Tri (insertion, sélection, à bulles, fusion, Dijkstra) (1) Tri par sélection Principe : on recherche le minimum dans la partie restante du tableau et on l’échange avec l’élément qui suit la partie déjà triée. Après k placements les k plus petits éléments du tableau sont déjà à leur place définitive G
Tri par sélection avec recherche séquentielle du minimum (1) Algorithme itératif Procédure tri-select-iter(ref tab: tableau [1..n] des entiers) Var i,j,k : entiers Début i:=1; Tant que i<n faire j:=i; Pour k:=i+1 à n faire {boucle de recherche de min } Si tab[k]<tab[j] j:=k; FinSi FinPour échanger(tab[j], tab[i]); i:=i+1; FinTantque Fin tri-select-iter
Tri par sélection avec recherche séquentielle du minimum (2) Version récursive Procédure tri-select(ref tab: tableau [1..n] des entiers, val i : entier) { appel avec i=1} Var i,j,k : entiers Début Si i<n alors {recherche séquentielle du minimum} Pour k:=i+1 à n faire {boucle de recherche de min } Si tab[k]<tab[j] j:=k; FinSi échanger(tab[j], tab[i]); {tri de la fin du tableau} Tri-select(tab, i+1) Fin tri-select
Analyse de complexité Opération fondamentale : comparaison. Pour tout tableau de taille n le nombre de comparaisons pour trouver le minimum est n-1 Maxc(n)=n-1+Maxc(n-1) pour n>1 et Maxc(1)=0 En itérant Le nombre de comparaisons ne dépend pas de la valeur des éléments
Tri (insertion, sélection, à bulles, fusion, Dijkstra) (2) Tri par insertion Principe : à la i-ème étape on insère le i-ème élément à son rang parmi les i-1 éléments précédents qui sont déjà triés entre eux. Après la i-ème étape les i plus petits éléments du tableau ne sont pas forcément à leur place Tri de « joueur des cartes » G
Tri par insertion: version récursive Procédure tri-insert(réf tab: tableau [1..n] des entiers, val i : entier) Var k,x : entiers Début Si i>1 alors tri-insert(tab,i-1) {tri du début de la liste} {recherche de la place de tab[i]} k:=i-1; x:=tab[i]; Tant que k>0 et tab[k]>x faire tab[k+1]=tab[k]; {décalage des éléments} k:=k-1; FinTantQue {on a tab[k] < x; la place de x est k+1} t[k+1]:=x; FinSi Fintri-insert
Analyse La procédure n’est pas récursive terminale (transformer en itérative est une tâche plus complexe) Complexité dans le pire des cas : le tableau est trié dans l’ordre décroissant Pour un tableau de n éléments on doit faire n-1 comparaisons après l’appel de tri-insert(tab,i-1) (sans compter la comparaison de k avec 0) Maxc(n)=n-1+Maxc(n-1) pour n>1 et Maxc(1)=0 ou si on compte le test de dépassement de la borne* * Sinon on peut utiliser la technique de sentinelle et insérer un élément inférieur à tous les éléments du tableau à tab [0]
Tri (insertion, sélection, à bulles, fusion, Dijkstra) (3) Tri à bulles Principe : on parcourt le tableau en effectuant un échange à chaque fois que l’on trouve deux éléments successifs qui ne sont pas dans le bon ordre. Il existe plusieurs versions tri à bulles avec parcours du début à la fin avec 2 boucles Pour imbriquées; tri à bulles amélioré (on retient l’indice de la dernière permutation); tri « shaker » - deux parcours du début à la fin, et inversement; tri avec parcours de la fin au début;
Tri à bulles Procédure tri-bulles(réf tab : tableau[1..n] d’entiers); Var i,j : entiers; Début i:=1; Tant que i<n faire Pour j:=n jusqu’à i+1 par pas -1 faire Si Tab[j]<Tab[j-1] alors échanger(Tab[j],Tab[j-1]) FinSi FinPour i:=i+1; FinTantque Fintri-bulles
Analyse Après k pas, les k plus petits éléments du tableau sont à leur place définitive. Le nombre de comparaisons Maxc(n)=n-1+Maxc(n-1) pour n>1 et Maxc(1)=0 Maxc(n)=Moyc(n)
Tri (insertion, sélection, à bulles, fusion, Dijkstra) (4) Tri par fusion …. ….
Algorithme de tri par fusion (2) Procédure Tri-Fusion(val A,p,r) Var q:entier Début Si p<r Alors Tri-Fusion(A,p,q) Tri-Fusion(A,q+1,r) Fusionner(A,p,q,r) FinSi Fin Tri-Fusion
Fusion de deux tableaux ordonnés Interclassement des deux tableaux : étant donnés un tableau tab1 de n éléments et un tableau tab2 de m éléments, il s’agit de construire un tableau tab3 trié, qui contient la réunion des éléments de tab1 et tab2 en conservant les répétitions. On utilisera la technique de sentinelle : dans la dernière case des tableaux augmentés (n+1) et (m+1) on insérera un élément maxelt d’emblée plus grand que les autres.
Fusion de deux tableaux ordonnés Procédure fusion-tab(réf tab1: tableau [1…n+1] d’éléments; réf tab2: tableau [1…m+1] d’éléments; réf tab3: tableau [1…n+m] d’éléments) Var i,j,k: entiers; Début i:=1;j=1;k:=1; tab1[n+1]:=maxelt; tab2[m+1]:=maxelt; Tant que k< m+n faire Si tab1[i]<tab2[j] alors tab3[k]:=tab1[i]; i:=i+1; sinon tab3[k]:=tab2[j]; j:=j+1; FinSi k:=k+1; FinTantQue Finfusion-tab
Analyse de complexité du tri-fusion Fusion: MaxNbr de tours de la boucle Tq = n+m Lors de chaque tour on a une comparaison et 2 affectations. Donc Max(n+m)= Tri-fusion: avec a=b=2 D’après le théorème général, cas 2 (cf. chap. 1)
Tri (insertion, sélection, à bulles, fusion, Dijkstra) (5) Algorithme de Dijkstra à deux couleurs Supposons que dans un tableau nous avons des nombres pairs et impairs (ou des objets de deux couleurs) Problème : placer les nombres pairs au début du tableau et les nombres impairs à la fin.
Tri de Dijkstra à deux couleurs P1: A gauche de l’indice G tous les objets sont rouges P2: A droite de l’indice D tous les objets sont bleus Problème : combler la zone d’incertitude G D
Tri de Dijkstra à deux couleurs(2) Faire décroitre la zone d’incertitude en conservant la validité des conditions G:=0;D:=N Tant que G<D Tant que (G<D && T[G+1] rouge) G:=G+1; FTQ Tant que (D>G&& T[D] bleu) D:=D-1; Si (G<D) alors permuter T[G+1] et T[D]; fin-Si Fin TantQue
Utilisation des tableaux de nombres : histogrammes matrices Tableau Hist [1…n] : permet de stocker les occurrences des valeurs d’une variable aléatoire X(t) : ai-1<xi<ai Problème : une variable aléatoire discrète prend des valeurs entières dans l’intervalle de 1…n. Proposer un algorithme de calcul de l’histogramme en
Matrices Une matrice peut être représentée par un tableau rectangulaire de nombres Ex: A : tableau[1…3][1..2] des entiers La transposée d’un matrice A est la matrice At en échangeant les lignes et les colonnes de A:
Matrices et vecteurs Vecteur est un tableau de nombres à une dimension Vect : tableau des entiers [1..n]. Vecteur colonne est équivalent à une matrice nx1, vecteur ligne est sa transposée. Vecteur unité ei est le vecteur dont la i-ème composante est égale à 1 et toutes les autres composantes sont égales à 0;
Opérations sur les matrices 1. Addition 2. Multiplication scalaire 3. Soustraction opposé de : 4. Multiplication
Algorithme direct de multiplication de matrices Fonction Multiplier_Matrices(réf A: tableau [1..m][1..n] d’entiers; ref B: tableau[1..n][1..p] d’entiers): tableau [1..m][1..p] d’entiers Var C: tableau [1..m][1..p] d’entiers; i,j,k: entiers; Début Pour i allant de 1 à m faire Pour j allant de 1 à p faire C[i][j]:=0; Pour k allant de 1 à n faire C[i][j]:= C[i][k]+A[i][k]*B[k][j]; FinPour retourner C; FinMultiplier_Matrices Complexité si A,B sont NxN
Calcul du déterminant Soit une matrice de taille nxn. Le ij-ème mineur est la matrice de taille (n-1)x(n-1) obtenue en supprimant la i-ème ligne et la j-ème colonne de A. Définition récursive du déterminant :