précédent | suivant | table des matières
Imaginé par Williams en 1964 (J.W.J. Williams: Algorithm 232: Heapsort. Communications of the ACM, 7, 6, 347-348 1964), ce tri est aussi appelé tri en tas ou tri maximier.
Ce tri est une accélération du tri par sélection et échange : une organisation préalable de l'ensemble de départ permet d'obtenir une sélection du maximum en un temps qui est dans l'ordre de log2n, ce qui permet à l'algorithme de redevenir optimum.
Le vecteur est considéré comme ayant une structure d'arbre binaire. On fera l’hypothèse que les éléments du tableau ont des indices qui vont de 0 à f (exclu). Un élément d'indice i du vecteur est considéré comme un nœud de l'arbre ; son fils gauche s'il existe se trouve à l'indice 2*i+1 et son fils droit s'il existe se trouve à l'indice 2*i+2. Ce nœud est une feuille si 2*i+1 est supérieur ou égal à f
De plus cet arbre est un maximier c'est à dire qu'il a la propriété d'être ordonné verticalement : chaque nœud contient une valeur supérieure à la valeur contenue dans ses descendants.
exemple :
|
|
correspond à l'arbre : |
La méthode descendre permet de réorganiser un tas dont seule la racine n'est pas à sa place. La racine se trouve à l'indice d.
void descendre( int t [], int d, int f){
int fg, fd, fm;
if(d*2+1 < f) {
fg = 2*d+1;
fd = 2*d+2;
if(fd>=nMax) fm = fg;
else
if (t[fg] > t[fd]) fm = fg; else fm = fd;
if( t[d] > t[fm]) return;
else{
int aux = t[d];
t[d] = t[fm];
t[fm] = aux;
descendre( t, fm, f);
}
}
}
La méthode remonter permet de remonter l'élément de rang n à sa place dans le tas formés par les éléments précédents :
void remonter( int t [], int n){
if(n==1) return;
else if( t[n-1] > t[n/2 - 1]){
int aux = t[n-1];
t[n-1] = t[n/2 - 1];
t[n/2 - 1] = aux;
remonter( t, n/2);
}
}
Pour organiser un tableau en tas, on peut choisir deux solutions :
|
void organiserTas( int t [] ){
for(int i = 2; i < t.length; ++i)
remonter(t, i);
}
|
|
void organiserTasBis( int t [] ){
for(int i = t.length/2; i>= 0; --i)
descendre(t, i, t.length);
}
|
Le tri par tas s’écrit alors :
void trierTas( int t [] ){
organiserTas( t, n);
for( int i = nt.length-1; i>0; --i ){
echanger(t[0], t[i]);
descendre(t, 0);
}