Académique Documents
Professionnel Documents
Culture Documents
VECTEURS
2.1. Introduction
Un vecteur est une application V de I dans E ; I est appelé ensemble des indices. 1
2.1.3. Définitions de type
Exemple
type structure date
entier jour, mois, an;
fin ;
structure personne
nom : chaine20 ;
adresse : chaine40 ;
naissance : date ;
marié : booléen ;
enfants : entier ;
fin; 2
On vient de définir :
• un type date composé de trois nombres entiers (jour, mois et an),
• un type personne composé d’un :
nom (chaîne de 20 caractères au plus),
adresse (chaîne de 40 caractères au plus),
variable naissance de type date,
variable booléenne marié
nombre entier enfants indiquant le nombre d’enfants de cette personne.
On dit que personne comporte cinq champs : nom, adresse, naissance, marié et
enfants. Pour sélectionner un champ on utilise la notation :
nom de variable.nom du champ.
Si pers est une variable de type personne ; on écrira : pers.nom, pers.adresse, pers,
marié, pers.enfants, pour accéder aux différents champs de la variable structurée pers.
On pourra de même accéder à l’ensemble de la date de naissance par pers.naissance,
ou bien à l’année seule par pers.naissance.an.
3
Ensemble des indices est toujours noté [1..n] dans la suite. Il peut être vide (si n = 0,
[1..n] est vide). Le vecteur est alors dit vide.
L’indice le plus petit (1) est appelé borne inférieure, le plus grand (n) est appelé borne
supérieure.
Notations : un vecteur est noté v[1..n] et mais s’il n’y a pas d’ambiguïté : v.
Un élément du vecteur est noté v[i] avec i [1..n].
Un vecteur peut être noté par l’ensemble de ses éléments : (v[1], v[2], …, v[n]) ou
(x1,…,xn) si xi Є v[i],
v
1 2 3 4 … n
v[1] v[2] v[3] v[4] ⦁v[n]
v[1..6] = (‘A’,’B’,’Z’,’A’,’C’,’D’),
v[2] ‘B’,
v[-4] non défini
v[0] non défini
v[4] ‘A’
v[5] ‘C’
v[7] non défini
5
Pour déclarer un vecteur, nou supposerons toujours qu’il existe une définition de type :
t tableau[nmax];
type vecteur tableau[nmax];
L’identificateur t pourra représenter n’importe quel type simple, structuré ou vecteur.
Sous-vecteur
Un sous-vecteur du vecteur v[1..n] est toute restriction de v à un intervalle consécutif
de [1..n]. Un sous-vecteur est noté comme un vecteur.
Exemple
Si v[1..5] = (7, -20, 40, 0, 1), alors les sous-vecteurs v[2..4] et v[1..3] sont formés par
les éléments : (-20, 40, 0) et (7, -20,40). 6
Relation d’ordre
Nous sommes amenés quelquefois à définir une relation d’ordre sur
l’ensemble E des valeurs d’un vecteur. Cette relation est notée, pour des
raisons de simplifications d’écriture, par le symbole <. Quel soit
l’ensemble E. De même, nous utilisons les opérateurs : >, ≤, ≥, =, et ≠.
Autres notations
A < v[1..n] signifie quelque soit j appartenant à [1..n], a < v[j].
7
2.2. Algorithmes traitant un seul vecteur
Nous traiterons des problèmes d’accès à une valeur donnée dans un vecteur.
8
Un parcours séquentiel dans l’ordre des indices décroissants, dit ordre
« de droite à gauche ».
Le schéma d’énumération séquentiel des éléments de v.
i := n ;
tantque i ≥ 1 faire
traiter(v[i]) ;
i := i - 1 ;
finfaire;
Algorithme récursif
procédure parcoursrec(d t v[], d entier i, entier n)
debproc
si i <= n alors
traiter(v[i]) ;
parcoursrec(v[i+1..n]) ;
finsi;
finproc;
On peut représenter la séquence des appels par le schéma suivant :
parcours(v, 1, 3) parcours(v, 2, 3]) parcours(v, 3, 3) parcours(v, 4, 3)
traiter(v[1]) 1 traiter(v[2]) 2 traiter(v[3]) 3 rien
parcours(v, 2, 3) 6 parcours(v, 3, 3) 5 parcours(v, 4, 3) 4
Exemple 2
Fonction qui calcule la somme des éléments d’un vecteur de nombres entiers (n>0, n est la taille
du vecteur). L’en-tête sera :
entier fonction somme(d entier v[], d entier n)
12
entier fonction somme(d entier v[], d entier n)
debfonc
entier s, i;
s := 0;
pour i := 1 haut n faire
s := s + v[i];
finfaire;
retourner s;
finfonc;
Exercice 2.1. Ecrire une procédure qui affiche les éléments d’un vecteur de nombres
entiers dans l’ordre des indices décroissants (« de droits à gauche »).
Exercice 2.2. Ecrire la même procédure sous forme récursive.
Exercice 2.3. Ecrire une fonction qui calcule le nombre d’occurrences de la valeur val
dans le vecteur v[1..n] composé de nombres entiers.
Exercice 2.4. Ecrire une fonction qui calcule le maximum des éléments d’un vecteur
v[1..n] de entiers.
Exercice 2.5. On appelle bigramme une suite de deux lettres. Ecrire une fonction qui
calcule le nombre d’occurrences d’un bigramme donné dans un vecteur de caractères.
13
2.2.2. Algorithme d’accès à un élément d’un vecteur
Soit un vecteur v[1..n].
L’accès par position est défini par la primitive d’indiçage v[i].
L’accès associatif est le plus courant. Soit elem une variable ayant une valeur de même type
que celles contenues dans v, on veut déterminer s’il existe un indice i [1..n] tel que v[i] = elem.
Cet accès peut être réalisé de plusieurs manières suivant que l’on suppose v trié ou non.
Algorithme : on doit parcourir le vecteur v[1..n], et à chaque fois on compare l’élément courant
v[i] à elem, si v[i] est différent de elem on prendra l’élément suivant. A priori, on écrirait
l’itération sous la forme :
tantque (i ≤ n) et (v[i] ≠ elem) faire …
Mais si elem є v[1..n], i atteint à la dernière itération la valeur n + 1, et on est amené alors à
effectuer un test sur v[n+1], valeur indéfinie.
On introduit donc l’opérateur "et alors" qui est en fait une évaluation de optimisée du "et "
classique. Il s’agit tout simplement de constater que si le premier terme du "et " est faux, il est
inutile d’examiner le second terme.
La table du "et alors" est la suivante.
14
Table du "et alors ".
A B A et alors B
vrai vrai vrai
vrai faux faux
faux non examiné faux
La valeur de C := A et alors B est équivalente à celle que donnerait la séquence
si A alors
C := B;
sinon
C := faux;
finsi;
On définit de même l’opérateur "ou sinon" , qui correspond à l’évaluation
optimisée du "ou" . Si le premier terme du "ou sinon" est vrai, il est inutile
d’examiner le second.
A B A ou sinon B
vrai non examiné vrai
faux vrai vrai
faux faux faux
15
La valeur de l’opération C := A ou sinon B est équivalente à celle que donnerait la
séquence
si A alors
C := vrai;
sinon
C := B;
finsi;
Remarques
La loi de De Morgan peut s’écrire, pour ces opérateurs :
non (a et alors b) = (non a) ou sinon (non b)
non (a ou sinon b) = (non a) et alors (non b)
16
L’algorithme s’écrit alors
booléen fonction accès1(d t v[], d entier n, d t elem)
debfonc
entier i;
i := 1;
tantque (i ≤ n) et alors (v[i] ≠ elem) faire
i := i + 1;
finfaire;
retourner i ≤ n ;
finfonc;
Etude du tableau de sortie
i>n V[i] = elem résultat
vrai non examiné faux
faux (i ≤ n) vrai vrai
faux (i ≤ n) faux impossible (tantque)
1ère ligne : i > n : on a dépassé la fin du vecteur, elem v[1..n], le résultat est faux.
2ème ligne : i ≤ n, v[i] = elem : on a elem є v[1..n], le résultat est vrai.
3ème ligne : i ≤ n, v[i] ≠ elem : (i>n) ou v[i] = elem n’est pas une assertion.
Le résultat de la fonction accès1 est donc identique à celui de (i ≤ n). 17
On peut écrire cet algorithme sous forme récursive. Dans ce cas, il faut introduire la
variable i au niveau des paramètres, en tant que borne inférieure du vecteur que l’on
étudie.
Le raisonnement est alors :
i>n résultat =faux *
i≤n
►► v[i] = elem résultat = vrai *
►► v[i] ≠ elem nouvel appel (récursif) avec v[i+1..n]
Dans ce cas, on recherche elem dans v[1..n], et on n’a plus besoin de variable auxiliaire i,
puisque la borne inférieure du vecteur est toujours égale à 1.
booléen fonction accèsRec2 (d t v[], d entier n; d t elem)
spécification { n≥0 } => { résultat = elem v[1..n] }
debfonc
si n = 0 alors retourner faux;
sinonsi v[n] = elem alors retourner vrai;
sinon retourner accèsrec1(v, n-1, elem);
finsi;
finfonc;
Si le vecteur n’est pas vide (n ≥ 1) un autre schéma d’algorithme consiste à prévoir la fin du
vecteur grâce à la variable i. Cette nouvelle version consiste à arrêter l’itération dès que i
atteint la valeur de n ou bien si on a trouvé l’élément cherché.
Avec le connecteur et alors, on pourrait éviter de vérifier dans le tantque si v[i] est égal à
elem lorsque i = n, mais on préfère présenter une version de l’algorithme qui évite l’emploi du
et alors même au prix d’un test supplémentaire lorsque v[n] = elem. 19
Algorithme : on doit parcourir le vecteur v[1..n], et à chaque fois on compare l’élément
courant v[i] à elem, si v[i] est différent de elem on prendra l’élément suivant. On arrête
l’itération dès que i atteint la valeur de n ou bien si on a trouvé l’élément cherché. A priori,
on écrirait l’itération sous la forme :
tantque (i < n) et (v[i] ≠ elem) faire …
Etude du tableau de sortie
Il faut préférer cet algorithme à accès1 si l’on programme dans un langage qui ne
connait pas l’opérateur logique « et alors ». Il est toujours possible de simuler le
« et alors » au moyen de divers artifices, tels que l’emploi d’une variable booléenne
à la place du second test. Mais il est bien plus simple de s’en passer complètement, à
l’aide de l’algorithme accès ci-dessus.
i := 1;
tantque v[i] ≠ elem faire
i := i + 1;
finfaire;
retourner i ≤ n;
finfonc;
Exercice 2.6.
Ecrire une fonction qui calcule le produit des éléments d’un vecteur v[1..n] d’entiers (penser
au cas où un élément serait nul).
Exercice 2.7.
Ecrire de plusieurs manières différentes une fonction entière qui délivre l’indice de la valeur
val dans v[1..n] si val appartient au vecteur v et 0 si val n’appartient pas à v. Préciser, dans
chaque cas, si c’est la première occurrence ou la dernière occurrence que l’on a trouvée.
22
b) vecteur ordonné (ou trié)
Si tous les éléments consécutifs d’un vecteur vérifient la relation d’ordre v[i-1]v[i], on dit que le
vecteur est trié par ordre croissant.
Dans toute la suite du cours, on appellera vecteur trié (ou ordonné) un vecteur trié par ordre
croissant.
Définition.
• un vecteur vide (n=0) est ordonné,
• un vecteur contenant un seul élément (n=1) est ordonné,
• un vecteur v[1..n], n>1, est ordonné si i [2..n], v[i-1] v[i].
On peut également donner une définition récursive.
• un vecteur vide (n=0) est ordonné,
• un vecteur contenant un seul élément (n=1) est ordonné,
• (v[1..i-1]ordonné, v[i-1] v[i]) v[1..i] ordonné pour i [2..n].
Cette définition récursive est à rapprocher des définitions récursives utilisées en mathématiques,
telles que la définition de n! :
n ! = 1 si n = 0,
n ! = n * (n - 1) ! si n 1.
Ces définitions sont utilisées pour construire des « algorithmes récursifs ».
Application immédiate de la définition est l’algorithme vérifiant qu’un vecteur est trié.
On veut écrire un algorithme d’en-tête :
fonction trié(d t v[], d entier n) : booléen
/spécification {n0} {résultat = v[1..n] est trié}
Il suffit de comparer tous les couples de deux éléments consécutifs en s’arrêtant dès qu’un couple
ne vérifie pas la relation d’ordre v[i-1]v[i]. 23
Cet algorithme est très semblable à celui de l’accès séquentiel accè1, mais que la valeur
retournée est vrai si et seulement si on a bien atteint i >n.
Notons que les cas n = 0 et n = 1 sont correctement traités puisque la valeur initiale de i
est supérieure à n dans ces cas.
booléen fonction trié(d t v[], d entier n)
debfonc
entier i;
i := 2;
tantque (i ≤ n) et alors (v[i] ≤ elem) faire
i := i + 1;
finfaire;
retourner i > n ;
finfonc;
Etude du tableau de sortie
i>n v[i - 1] > v [i] résultat
vrai non examiné vrai
faux (i ≤ n) vrai faux
faux (i ≤ n) faux impossible (tantque)
1 i n
Ensuite, il ne reste plus qu’à vérifier l’égalité elem = v[i] pour savoir si elem est
présent ou non dans le vecteur trié.
booléen fonction trié(d t v[], d entier n, d t elem)
debfonc
entier i;
i := 1;
tantque (i ≤ n) et alors (v[i] < elem) faire
i := i + 1;
finfaire;
retourner (i ≤ n) et alors (v[i] = elem) ;
finfonc; 25
Etude du tableau de sortie
i>n v[i] elem résultat
vrai non examiné faux
faux (i n) vrai vrai ssi elem = v[i]
faux (i n) faux impossible (tantque)
1ère ligne : i>n, on a dépassé la fin du vecteur, donc elem v[1..n]. Le résultat est faux.
2ème ligne : i n, v[i] elem, si v[i]=elem alors elem appartient à v et le résultat prend
la valeur vrai, sinon il prend la valeur faux.
3ème ligne : i n, v[i] < elem, (i < n) ou sinon (v[i] elem) n’est pas une assertion.
Tableau de sortie
i=n V[i] ≥ elem résultat
vrai vrai vrai ssi elem = v[i]
vrai faux faux
faux (i < n) vrai vrai ssi elem = v[i]
faux (i < n) faux Impossible (tantque)
27
Si le vecteur n’est pas vide, on peut aussi comparer l’élément que l’on cherche avec
celui du dernier élément de v[1..n]. Alors, si elem > v[n], l’algorithme est terminé,
l’élément n’appartient pas à v. Si elem v[n], on peut effectuer un parcours de
gauche à droite avec une seule condition (v[i]<elem) au niveau du tantque car on
est certain que i est borné par n (puisque v[n] elem).
L’algorithme est alors :
booléen fonction accesTrié3(d t v[], d entier n, d t elem)
//spécification {n > 0, v[1..n] trié}{résultat = elem v[1..n]}
debfonc
entier i;
si elem > v[n] alors retour faux ;
sinon
i := 1 ;
tantque v[i] < elem faire
i++;
finfaire;
retourner v[i] = elem ;
finsi;
finfonc;
28
Une dernière version possible consisterait à utiliser une "sentinelle« , qui serait cette fois non
pas la valeur ci, mais un majorant (valeur supérieure dans v[1..n], high value).
Exercice 2.8.
Ecrire l’algorithme de recherche d’une valeur dans un vecteur trié, à l’aide d’une sentinelle.
Exercice 2.9.
Ecrire une fonction qui retourne la place de la première occurrence de la valeur val dans le
vecteur trié v[1..n] si val appartient au vecteur v, et 0 si val n’appartient pas à v.
Exercice 2.10.
Même question pour la dernière occurrence.
29
c) Recherche dichotomique
En comparant elem à v[m], on peut décider, si elem n’est pas égal à v[m], à quel sous-
vecteur il peut appartenir :
• à v[1 .. m-1] si elem < v[m],
• à v[m+1 .. n] si elem > v[m].
On est alors ramené au même problème que précédemment : rechercher elem dans un
vecteur (v[1..m-1] ou v[m+1..n]). Par contre si elem est égal à v[m], l’algorithme est
terminé. 30
On est donc amené à déterminer une suite de sous-vecteurs : v1, v2,…, vk telle que
chaque sous-vecteur vi a un nombre d’éléments strictement inférieur à la taille du
vecteur précédent vi-1.
Remarque
On choisit l’indice m tel que la taille des deux sous-vecteurs v[1..m-1] et v[m+1..n] soit
la même (à un élément près). La taille des vecteurs de la suite v1, v2,…, vk est divisée
par deux à chaque pas : n, n/2, …,n/2k-1. On a donc au plus « partie entière de log2(n)»
sous-vecteurs non vides.
booléen fonction dich(d t v[], entier n, d entier elem)
debfonc
entier inf, sup, n; booléen trouvé;
trouvé := faux ; inf := 1 ; sup := n ;
tantque (infsup) et (non trouvé) faire
m := (inf + sup) div 2 ;
si v[m] = elem alors trouvé := vrai ;
sinonsi v[m] < elem alors inf := m + 1 ;
sinon sup := m – 1 ;
finsi;
finfaire;
retourner trouvé ;
finfonc; 31
Etude de tableau de sortie
inf > sup trouvé résultat : dich
vrai vrai impossible
vrai faux faux
faux vrai vrai
faux faux Impossible (tantque)
Exercice 2.11. Modifier les fonctions dich données ci-dessus afin qu’elles délivrent la
place de elem dans le vecteur v s’il y figure, et 0 s’il n’y figure pas (on supposera qu’
elem ne figure pas plus d’une fois dans v, on dira que le vecteur est trié sans répétition).
34
2.3. Tris d’un vecteur
Soit v[1..n] , trier le vecteur v consiste à construire un vecteur v’[1..n] tel que :
• v’ soit trié,
• v et v’ contiennent les mêmes éléments.
Méthode
Construire vtrié[1..n] à partir de v[1..n] tel que vtrié[i-1] vtrié[i], i [2..n].
Pour i = 2, on a vtrié[1] vtrié[2..n]. vtrié[1] est donc égal à : minimum(v[1..n]).
Il faut maintenant substituer dans v à la valeur du minimum trouvé, une valeur qui ne
sera plus atteinte par la suite, lors de la recherche d’un nouveau minimum. Il suffit de
prendre comme valeur de remplacement un majorant de v[1..n] : le maximum des
éléments de v[1..n].
Exemple : soit à trier les lettres du mot BATEAUX : le maximum est égal à ‘X’.
35
V j (indice du minimum) V après remplacement Vtrié
1 B/ATEAUX 2 BXTEAUX A
2 BXTEAUX 5 BXTEXUX AA
3 BXTEXUX 1 XXTEXUX AAB
4 XXTEXUX 4 XXTXXUX AABE
5 XXTXXUX 3 XXXXXUX AABET
6 XXXXXUX 6 XXXXXXX AABETU
7 XXXXXXX fini AABETUX
Le type t est le type des éléments du vecteur V. On notera que l’on a été amené à modifier le
vecteur initial V, c’est pourquoi il est passé en paramètre « donnée-résultat ». Si on voulait
conserver sa valeur initiale, il faudrait le recopier dans un autre vecteur avant d’appeler cette
procédure.
Exercice 2.12.
Modifier triRemplacement pour qu’il trie les éléments de V dans l’ordre décroissant.
38
Evaluation du coût de l’algorithme
• Nombre de comparaisons :
On appelle la fonction maximum une fois d’où : n-1 comparaisons ou (n-1 accès).
D’autre part, à chaque itération, on appelle la fonction indmin qui demande n-1
comparaisons (2(n-1) accès). Comme on effectue n-1 itérations, on effectue (n-1)(n-1)
comparaisons pour l’appel de la fonction indmin (≈2n2 accès).
On obtient donc : n(n-1) comparaisons (≈ 2n2 accès).
40
En conclusion
Place occupée 2nt
Nombre de comparaisons n(n-1) (≈2n2 accès)
Nombre d’affectations Cas favorable 2n (3n accès)
Cas défavorable ≈3n (≈4n accès)
Exemple
Si n=1000, t=20 octets.
Place occupée : 40 000 octets.
Nombre de comparaisons : de l’ordre de 1 000 000.
Nombre d’affectations : de l’ordre de 2 500 en moyenne.
Méthode
Supposons traités i – 1 (1 i < n) éléments du vecteur v. On a la configuration suivante:
v[1..i-1]trié et v[i..n] non trié.
41
V[1..i-1] trié V[i..n] non traité
1 i-1 i n
Le vecteur v est la concaténation de 2 vecteurs : v[1..i-1] triés et v[i..n] non traités.
D’autre part tous les éléments du sous-vecteur v[1..i-1] sont inférieurs ou égaux à tous
les éléments du sous-vecteurs v[i..n].
Algorithme : à chaque parcours du vecteur v[i..n], on cherche l’indice du minimum (j),
si j≠i , on permute les valeurs v[i] et v[j] sinon on ne fait rien, puis à chaque cas, on
prend l’élément suivant.
Exemple : soit à trier dans l’ordre alphabétique les lettres du mot BATEAUX.
i j trié/ non traité éléments à permuter Après permutation, trié/non
traité
1 2 /BATEAUX B et A A/BTEAUX
2 5 A/BTEAUX B et A AA/TEBUX
3 5 AA/TEBUX T et B AAB/ETUX
4 4 AAB/ETUX pas de permutation AABE/TUX
5 5 AABE/TUX pas de permutation AABET/UX
6 6 AABET/UX pas de permutation AABETU/X
7 AABETU/X fini AABETUX/ 42
Algorithmes : supposons que nous disposions de 2 primitives.
• entier fonction indmin(d t v[], d entier i, d entier n)
spécification {1i<n} {résultat = j, j[i..n], v[j] v[i..n]}
• procédure permut(dr entier a, b)
spécification {a = x, b = y} {a = y, b = x }
Exercice 2.13
Modifier le tri par permutation pour obtenir un vecteur trié dans l’ordre décroissant.
Exemple
Pou n = 1000, t = 20 octets,
Place occupée : 20020 octets
Nombre de comparaisons : 500 000,
Nombre d’affectations : de l’ordre de 1500 en moyenne.
On constate que cet algorithme est bien meilleur que le précédent car il a permis de
gagner de la place et du temps, ce qui est très rare en informatique. Le plus souvent,
un gain de temps a pour contrepartie une perte de place et un gain de place a pour
contrepartie une perte de place. Cela signifie que l’algorithme triRemplacement est
très mauvais et qu’il ne faut jamais l’utiliser. Il a été donné uniquement à titre
pédagogique. 46
2.3.3. Tri par la méthode des bulles
Il s’agit d’une méthode qui opère par permutations à l’intérieur du vecteur à trier. La
première version (non optimisée) n’est qu’une variante , moins efficace de tri par
permutation. la seconde version (optimisée) est généralement un peu meilleure.
Principe
Après avoir traité i-1 (1 i < n) éléments, on a la situation suivante :
v[1..i-1]trié v[i..n] non trié
1 i-1 i n
i j-1 j n
avec v[j] v[j..n].
Exemple : soit à ranger en position 1 l’élément minimum du vecteur BATEAUX.
J non traité/ traité éléments à comparer Après permutation non traité/ traité
7 BATEAU/X U et X pas de permutation BATEA/UX
6 BATEA/UX A et U pas de permutation BATE/AUX
5 BATE/AUX E et A permutation BAT/AEUX
4 BAT/AEUX T et A permutation BA/ATEUX
3 BA/ATEUX A et A pas de permutation B/AATEUX
2 B/AATEUX B et A permutation /ABATEUX
On constate que, non seulement l’élément minimum A a bien été rangé dans la position
voulue, mais que l’ordre général s’est accru : le second A a été aussi déplacé vers la
gauche. C’est cette opération qui donne son nom à la méthode : on fait remonter les
48
bulles vers la surface : les éléments les plus légers sont transportés vers la gauche.
L’algorithme de remontée s’écrit donc.
j := n;
tantque j > i faire
si v[j -1] > v[j] alors permut(v[j-1], v[j]);
finsi;
j := j – 1 ;
finfaire;
49
Soit à trier dans l’ordre alphabétique les lettres du mot « BATEAUX ».
On peut maintenant écrire une première version de l’algorithme complet du tri par la
méthode des bulles.
50
procédure tribulle1(dr t v[], d entier n)
debproc
entier i, j;
i := 1;
tantque i < n faire
j := n ;
tantque j > i faire
si v[j -1] > v[j] permut(v[j-1], v[j]);
finsi;
j := j – 1;
finfaire;
i := i + 1;
finfaire;
finproc;
Version avec des instructions pour.
procédure tribulle1(dr t v[], d entier n)
debproc
entier i, j;
pour i := 1 haut < n-1 faire
pour j := n bas i+1 faire
si v[j -1] > v[j] alors permut(v[j-1], v[j]) ;
finsi;
finfaire;
finfaire; 51
finproc;
Evaluation du coût de l’algorithme
Les comparaisons entre les éléments du vecteur sont effectuées dans l’itération «tantque j>i ».
On effectue une comparaison à chaque itération d’où : n-i comparaisons, soit 2(n-i) accès.
l’itération « tantque j>i » de trouve placée dans l’itération « tantque i<n » .
Pour i=1, on effectue n-1 comparaisons,
Pour i=2, on effectue n-2 comparaisons,
…
Pour i=n-1, on effectue 1 comparaison,
Le nombre total de comparaisons nc est égal à : nc = n(n-1)/2 d’où n(n-1) accès.
Pour le nombre de permutations, on a deux cas :
• le cas favorable où on effectue o permutations,
• le cas défavorable où on effectue une permutation à chaque comparaison :
n(n-1)/2 permutations, donc 2n(n-1) accès.
La place occupée est le même que dans l’algorithme de tri précédent.
Les performances sont identiques sauf en ce qui concerne le nombre de permutations qui peut
être beaucoup plus grand.
En conclusion :
Cette fois il est impossible d’écrire un algorithme avec deux boucles pour.
54
procédure tribulle2( dr t v[], d entier n)
spécification(n>0)(v[1..n] trié)
debproc
entier i, j; booléen onapermute;
i := 1; onapermute := vrai;
tantque onapermute faire
onapermute := faux;
pour j := n bas i+1 faire
si v[j -1] > v[j] alors
permut(v[j-1], v[j]);
onapermute := vrai;
finsi;
finfaire;
i := i + 1;
finfaire;
finproc;
55
Exercice 2.14 : Modifier les procédures triBulle1 et triBulle2 pour que V soit trié dans
l’ordre décroissant.
56
2.4. Algorithmes de mise à jour d’un vecteur
Nous nous limitons à des algorithmes d’insertion et de suppression d’un seul élément
dans un vecteur.
57
2.4.2. Insertion d’un élément dans un vecteur trié
Il s’agit d’ajouter au vecteur trié vtrie[1..n], l’élément elem pour obtenir un nouveau
vecteur trié vtrié[1..n+1].
Une méthode consiste à :
• chercher la place de l’élément à insérer,
• effectuer l’insertion de cet élément.
L’algorithme d’insertion
procédure insertion(dr t vtrie[], d entier n, d entier elem)
debproc
entier p;
si n = 0 alors
vtrie[1] := elem ; n := 1;
sinon /* n > 0 */
p := posit(vtrie, n, elem);
insertplace(vtrie, n, elem, p) ;
finsi;
finproc;
Où posit est une fonction délivrant la place de l’élément elem.
insertplace une fonction d’insertion de elem à la place p. 58
Recherche de la place de l’élément à insérer
On cherche l’indice p (p [1..n+1]) tel que la relation suivante soit vérifiée
vtrie[1..p-1] elem < vtrie[p..n]
En effet, on cherche une place le plus à droite possible, afin d’avoir à effectuer le
moins possible de décalages pour l’insertion.
Exemple. Si le vecteur v contient les lettres : A B B C F F G, on devra trouver :
posit(v, 6, ‘A’) = 1
posit(v, 6, ‘B’) = 3
posit(v, 6, ‘C’) = 4
posit(v, 6, ‘F’) = 6
posit(v, 6, ‘G’) = 7
On remarquera que pour p = 1, la relation se réduit à elem < vtrie[1..n]
et que pour p = n + 1 elle se réduit à vtrie[1..n] elem.
Cette recherche peut être effectuée par une méthode séquentielle ou dichotomique.
Méthode séquentielle
On commence par chercher si p = 1 ; sinon il reste à chercher p dans l’intervalle
[2 ..n+1]. Pour cela, on effectue un parcours de droite à gauche .
Hypothèse : vtrie[1] elem < vtrie[i+1..n]
• vtrie[i] elem p = i+1 ; *
• vtrie[i] > elem i = i-1 ; H
Itération : tantque(vtrie[i] > elem)… 59
Initialisation
• vtrie[1] > elem p = 1; *
• vtrie[1] elem i = n ; H
L’algorithme
entier fonction posit(d t v[], d entier n, d t elem)
//spécif (n>0, vtrie[1..n] trié) (résultat=p, vtrie[1..p-1]elem<vtrie[p..n], p[1..n+1])
debfonc
entier p, i;
si vtrie[1]>elem alors p:=1;
sinon
i := n;
tantque(vtrie[i] > elem)i:=i-1;
p := i+1;
finfaire;
finsi;
retourner p;
finfonc;
Méthode dichotomique
On traite d’abord le cas de p=n+1. Ensuite il reste à chercher p[1..n]
tel que vtrie[1..p-1] elem < vtrie[p..n]. 60
entier fonction posit(d t vtrie[], d entier n, d t elem)
debfonc
entier p, inf, sup, m;
si vtrie[n]elem alors p := n + 1;
sinon
inf := 1 ; sup := n ;
tantque inf < sup faire
m := (inf + sup)/2;
si vtrie[m]elem alors inf := m + 1;
sinon sup := m;
finsi;
finfaire;
p := sup;
finsi;
retourner p;
finfonc;
61
Insertion de l’élément à sa place
Connaîssant la place p de l’élément à insérer, le nouveau vecteur vtrie[1..n+1] est égal
à la concaténation de 3 vecteurs vtrie[1..p-1] || elem || vtrie[p+1..n+1].
où vtrie[p+1..n+1] est identique à vtrie[p..n].
Il suffit d’effectuer une translation à droite d’une position des éléments de vtrie[p..n] et
ensuite d’affecter elem à vtrie[p].
procédure insertplace(dr t vtrié[], d entier n, d t elem, d entier p)
debproc
pour i := n bas p faire vtrié[i+1] := vtrié[i];
finfaire;
n++;
vtrie[p] := elem;
finproc;
Exercice 2.17: on souhaite maintenant remplacer toutes les occurrences d’un sous-
vecteur donné dans un vecteur par un autre. Exemple : on veut remplacer toutes les
occurrences de « très » dans la phrase « il fait très beau et très chaud aujourd’hui ».
On obtiendra donc « il fait assez beau et assez chaud aujourd’hui »
67