Nous allons voir dans ce chapitre l'utilisation du tri bulle boustrophédon pour trier un tableau d'entiers. Mais auparavant nous allons expliquer le tri à bulle (ou tri bulle) simple. Soit un tableau d'entiers non trié. Prenons par exemple :
9, 2, 15, 7, 3, 1, 6, 13, 17, 4
Le tri bulle consiste à parcourir le tableau de gauche à droite et chaque fois qu'on est sur un nombre, si son voisin droit a une valeur inférieure, alors on permute ces deux nombres. Une fois qu'on est au bout, si une permutation a eu lieu alors on recommence depuis le début.
Voici l'exemple: On est sur le premier nombre. Son voisin est plus petit que lui donc on les permute pour obtenir:
2, 9, 15, 7, 3, 1, 6, 13, 17, 4
Ensuite on avance pour tomber sur le deuxième nombre. Pas de permutation car 9<15. On avance. On est sur le troisième nombre. Comme 7<15 alors on les permute et on obtient :
2, 9, 7, 15, 3, 1, 6, 13, 17, 4
On passe ensuite au quatrième nombre qui est ici 3 et qui est plus petit que son voisin droit, donc on les permute:
2, 9, 7, 15, 1, 3, 6, 13, 17, 4
On continue, et on trouve une permutation à la dernière position :
2, 9, 7, 15, 1, 3, 6, 13, 4, 17
On est arrivé à la fin, mais des permutations ont eu lieu, donc on recommence depuis le début; voici les étapes successives:
position 1 : 2, 9, 7,
15, 1, 3, 6, 13, 4, 17 --> pas de
changement
position 2 : 2, 7,
9, 15, 1,3, 6, 13, 4, 17
position 3 : 2, 7, 9,
15, 1,3, 6, 13, 4, 17 --> pas de
changement
position 4 : 2, 7, 9, 1,
15, 3, 6, 13, 4, 17
position 5 : 2, 7, 9,
1, 3, 15, 6, 13, 4, 17
position 6 : 2, 7, 9,
1, 3, 6, 15, 13, 4, 17
position 7 : 2, 7, 9,
1, 3, 6, 13, 15, 4, 17
position 8 : 2, 7, 9,
1, 3, 6, 13, 4, 15, 17
position 9 : 2, 7, 9,
1, 3, 6, 13, 4, 15, 17 --> pas de
changement
Mais on a eu des permutations, donc on recommence
position 1 : 2, 7, 9,
1, 3, 6, 13, 4, 15, 17 --> pas de
changement
position 2 : 2, 7, 9,
1, 3, 6, 13, 4, 15, 17 --> pas de
changement
position 3 : 2, 7, 1,
9, 3, 6, 13, 4, 15, 17
position 4 : 2, 7, 1, 3,
9, 6, 13, 4, 15, 17
position 5 : 2, 7, 1,
3, 6, 9, 13, 4, 15, 17
position 6 : 2, 7, 1,
3, 6, 9, 13, 4, 15, 17 --> pas de
changement
position 7 : 2, 7, 1,
3, 6, 9, 4, 13, 15, 17
position 8 : 2, 7, 1,
3, 6, 9, 4, 13, 15, 17 --> pas de
changement
position 9 : 2, 7, 1, 3, 6, 9, 4, 13, 15, 17 --> pas de changement
A cette étape nous avons eu 4 permutations, donc on recommence:
position 1 : 2, 7, 1,
3, 6, 9, 4, 13, 15, 17 --> pas de
changement
position 2 : 2, 1,
7, 3, 6, 9, 4, 13, 15, 17
position 3 : 2, 1, 3,
7, 6, 9, 4, 13, 15, 17
position 4 : 2, 1, 3, 6,
7, 9, 4, 13, 15, 17
position 5 : 2, 1, 3,
6, 7, 9, 4, 13, 15, 17 --> pas de
changement
position 6 : 2, 1, 3,
6, 7, 4, 9, 13, 15, 17
position 7 : 2, 1, 3,
6, 7, 4, 9, 13, 15, 17 --> pas de
changement
position 8 : 2, 1, 3,
6, 7, 4, 9, 13, 15, 17 --> pas de
changement
position 9 : 2, 1, 3, 6, 7, 4, 9, 13, 15, 17 --> pas de changement
A cette étape nous avons eu 4 permutations, donc on recommence:
position 1 : 1, 2,
3, 6, 7, 4, 9, 13, 15, 17
position 2 : 1, 2, 3,
6, 7, 4, 9, 13, 15, 17 --> pas de
changement
position 3 : 1, 2, 3,
6, 7, 4, 9, 13, 15, 17 --> pas de
changement
position 4 : 1, 2, 3,
6, 7, 4, 9, 13, 15, 17 --> pas de
changement
position 5 : 1, 2, 3,
6, 4, 7, 9, 13, 15, 17
position 6 : 1, 2, 3,
6, 4, 7, 9, 13, 15, 17 --> pas de
changement
position 7 : 1, 2, 3,
6, 4, 7, 9, 13, 15, 17 --> pas de
changement
position 8 : 1, 2, 3,
6, 4, 7, 9, 13, 15, 17 --> pas de
changement
position 9 : 1, 2, 3, 6, 4, 7, 9, 13, 15, 17 --> pas de changement
A cette étape nous avons eu 2 permutations, donc on recommence:
position 1 : 1, 2, 3,
6, 4, 7, 9, 13, 15, 17 --> pas de
changement
position 1 : 1, 2, 3,
6, 4, 7, 9, 13, 15, 17 --> pas de
changement
position 1 : 1, 2, 3,
6, 4, 7, 9, 13, 15, 17 --> pas de
changement
position 1 : 1, 2, 3, 4,
6, 7, 9, 13, 15, 17
position 5 : 1, 2, 3,
4, 6, 7, 9, 13, 15, 17 --> pas de
changement
position 6 : 1, 2, 3,
4, 6, 7, 9, 13, 15, 17 --> pas de
changement
position 7 : 1, 2, 3,
4, 6, 7, 9, 13, 15, 17 --> pas de
changement
position 8 : 1, 2, 3,
4, 6, 7, 9, 13, 15, 17 --> pas de
changement
position 9 : 1, 2, 3, 4, 6, 7, 9, 13, 15, 17 --> pas de changement
A cette étape nous avons eu une permutation, donc on recommence, et quand on arrive à la fin aucune permutation n'a été effectuée, donc le tableau est trié et le programme s'arrête. Le tri a été réalisé en 7 boucles.
On constate que la première amélioration possible est de limiter le
nombre d'avancées du curseur. En effet, chaque boucle sur les éléments du
tableau a pour effet de ramener le plus grand nombre rencontré à la fin du
tableau (ou à sa position correcte). Sachant donc qu'après le premier parcours
le nombre 17 se trouve à la fin, il ne sera plus nécessaire à l'étape suivante
d'aller jusqu'à 17, il suffira de s'arrêter à son prédécesseur. Ainsi à chaque
étape le nombre de paires à comparer diminue.
Mais on peut encore améliorer cet algorithme : c'est le tri bulle
boustrophedon.
Le parcours du tableau se fait alternativement de gauche à droite et de
droite à gauche.
Quand on va de gauche à droite (cas ci-dessus), le plus grand nombre se
trouve à l'extrémité droite du tableau (et la nouvelle extrémité devient don
prédécesseur).
Quand on va de droite à gauche, le plus petit nombre se trouve à
l'extrémité gauche du tableau et la nouvelle extrémité gauche devient son
successeur. Quand les deux extrémités se rejoignent, alors le tableau est trié
et le programme s'arrête. On peut aussi affirmer que si pendant un parcours (de
gauche à droite ou inversement) aucune permutation n'a lieu, alors le tableau
est trié.
Pour réaliser le tri bulle boustrophedon, nous allons réaliser deux procédures qui s'appellent l'une l'autre, d'où le nom de récursivité croisée.
Dans ce programme, nous allons utiliser une procédure de permutation de deux nombres. Voici un moyen d'échanger la valeur de deux nombres sans utiliser de variable auxiliaire :
soit deux variables a et b; a=3, b=5. On veut avoir à la fin a=5 et b=3.
On fait donc les opérations suivantes :
a
:= a + b = 8
b
:= a - b = 8 - 5 = 3
a
:= a - b = 8 - 3 = 5
Et comme on peut le constater, les deux valeurs sont échangées.
Nous allons voir les structures de données utilisées : le type "tab" qui est un tableau d'entiers, un tableau de type "tab" qui est un tableau de constantes (et que nous allons copier dans la variable "t2" pour pouvoir effectuer le tri dessus).
Comme on a une récursivité croisée, et comme nous n'avons pas utilisé la programmation orientée objet, il faut déclarer l'une des deux procédures en "forward".
type tab = array[1..10] of integer;
const t1: tab = (9, 2, 15, 7, 3, 1, 6, 13, 17, 4);
var t2: tab;
procedure arriere(var t: tab; limg, limd: integer); forward;
procedure affiche(t: tab);
var i: integer;
s: string;
begin
s := '';
for i := 1 to 10 do
s := s + inttostr(t[i]) + '; ';
form1.memo1.lines.add(s);
end;
procedure echange(var a, b: integer);
begin
a := a + b;
b := a - b;
a := a - b;
end;
procedure avant(var t: tab; limg, limd: integer);
var permute: boolean;
i: integer;
begin
permute := false;
for i := limg to limd - 1 do
if t[i] > t[i + 1] then
begin
echange(t[i], t[i + 1]);
permute := true;
end;
if permute then
begin
affiche(t);
arriere(t, limg, limd - 1);
end;
end;
procedure arriere(var t: tab; limg, limd: integer);
var permute: boolean;
i: integer;
begin
permute := false;
for i := limd downto limg + 1 do
if t[i] < t[i - 1] then
begin
echange(t[i], t[i - 1]);
permute := true;
end;
if permute then
begin
affiche(t);
avant(t, limg + 1, limd);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
move(t1, t2, sizeof(t1));
avant(t2, 1, 10);
end;
Télécharger le code source Delphi