1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| //Techniquement, on pourrait se passer de offsetDest, puisqu'il devrait toujours être égal à ixDebut
void fusion(int const* pcSource, size_t ixDebut, size_t ixMilieu, size_t ixFin, int *pDest, size_t offsetDest)
{
size_t ixGauche = ixDebut, ixDroite = ixMilieu;
size_t ixDest = 0;
while(ixGauche < ixMilieu && ixDroite < ixFin) //Tant qu'on n'a pas lu complètement les deux plages du tableau
{
if(ixGauche >= ixMilieu)
{
//On a lu toute la partie gauche, il faut donc ajouter la partie droite au tableau destination
int valeurRestante = pcSource[ixDroite++];
pDest[offsetDest + ixDest++] = valeurRestante;
}
else if(ixDroite >= ixFin)
{
//On a lu toute la partie droite, il faut donc ajouter la partie gauche au tableau destination
int valeurRestante = pcSource[ixGauche++];
pDest[offsetDest + ixDest++] = valeurRestante;
}
else
{
//Il en reste des deux côtés: Il faut comparer les valeurs (sans les consommer)
//et ajouter la plus petite à la destination (en la consommant)
int valeurGauche = pcSource[ixGauche];
int valeurDroite = pcSource[ixDroite];
int valeurMin;
//Je pourrais utiliser l'opérateur conditionel ternaire ici,
//mais c'est déjà assez compliqué avec les post-incrémentations
if(valeurGauche <= valeurDroite)
valeurMin = pcSource[ixGauche++];
else
valeurMin = pcSource[ixDroite++];
pDest[offsetDest + ixDest++] = valeurMin;
}
}//while
}
void triFusionRec(int *pTableau, size_t ixDebut, size_t ixFin, int *pAutreTableau)
{
if(ixFin - ixDebut <= 1)
{
if(ixFin - ixDebut > 0)
pTableau[ixDebut] = pAutreTableau[ixDebut];
return;
}
{
size_t ixMilieu = ixDebut + (ixFin - ixDebut)/2;
//On trie les sous-tableaux en inversant l'ordre, les résultats triés seront donc dans pAutreTableau
triFusionRec(pAutreTableau, ixDebut, ixMilieu, pTableau);
triFusionRec(pAutreTableau, ixMilieu, ixFin, pTableau);
//Fusionne les sous-tableaux triés (dans pAutreTableau) vers pTableau
fusion(pAutreTableau, ixDebut, ixMilieu, ixFin, pTableau, ixDebut);
}
}
int triFusion(int *pTableau, size_t taille)
{
int* pAutreTableau = malloc(taille * sizeof(int))
if(pAutreTableau==NULL)
return -1;
memcpy(pAutreTableau, pTableau, taille * sizeof(int));
triFusionRec(pTableau, 0, taille, pAutreTableau);
free(pAutreTableau);
return 0;
} |
Partager