Reputation: 1161
I make a c++ project to compare different algorithm complexity. I have a vector of Circle vector<Disque>
and i would like to sort this vector by attribute x of circle (x-axis the most in left => x-axis-radius). I've implement merge-sort algorithm but doesn't work and dont know why.
Merge sort implementation :
/**
* Méthode qui permet de fusionner les tableaux qui ont été séparés afin de trier le tableau final
* @param indice_bas
* @param milieu
* @param indice_haut
* @param taille
*/
void fusion(int indice_bas, int milieu, int indice_haut, vector<Disque> tableau) {
// Déclaration de différents indices pour la fusion
int h,i,j,k;
// Déclaration du tableau intérmediaire qui permet de stocké les disques du tableau
vector<Disque> tab_tmp;
// Initialisation des indices
h = indice_bas;
i = indice_bas;
j = milieu+1;
// Tant que nous avons pas trié l'ensemble du tableau
while((h <= milieu) && (j <= indice_haut)) {
// Si la valeurs de gauche est plus petite que celle de droite
if((tableau[h].getPoint().getX() - tableau[h].getRayon()) <= (tableau[j].getPoint().getX() - tableau[j].getRayon())) {
// On insère la valeur de gauche et on incrémente l'indice h
tab_tmp.push_back(tableau[h]);
h++;
} else {
// Sinon on interverti les valeurs du tableau afin de les remettrent dans l'ordre et on incrémente l'indice j
tab_tmp.push_back(tableau[j]);
j++;
}
// Incrémentation de i car tab_tmp[i] possède désormais une valeur
i++;
}
// Si il reste des valeurs à insérer dans le tableau temporaire, on les insère suivant si elles sont dans le tableau de droite ou de gauche
if(h > milieu) {
// Boucle qui permet d'insérer les valeurs restantes
for(k = j; k <= indice_haut; k++)
{
tab_tmp.push_back(tableau[k]);
i++;
}
} else {
// Boucle qui permet d'insérer les valeurs restantes
for(k = h; k <= milieu; k++) {
tab_tmp.push_back(tableau[k]);
i++;
}
}
// On replace les valeurs une à une dans le tableau que nous avons trié
for(k = indice_bas; k <= indice_haut; k++){
tableau[k] = tab_tmp[k];
}
}
/**
* Méthode tri fusion qui permet de trier les abscisse du point central d'un disque.
* Choix de cet algorithme car la complexité est en n log n
* @param indice_bas
* @param indice_haut
*/
void tri_fusion(int indice_bas, int indice_haut, vector<Disque> tableau, int taille){
// On déclare un indice qui correspond au milieu du tableau à trier pour effectuer un split
int milieu;
if(indice_bas < indice_haut) {
// Calcul du milieu du tableau
milieu = indice_bas + (indice_haut - indice_bas) / 2;
// On appel récursivement la méthode de tri fusion jusqu'à la division de tous les tableaux
tri_fusion(indice_bas, milieu, tableau, taille);
tri_fusion(milieu + 1, indice_haut, tableau, taille);
fusion(indice_bas, milieu, indice_haut, tableau);
}
}
Main :
// Fonction main qui est le point d'entrée du programme
int main(int argc, const char * argv[]) {
// Permet de générer plus d'aléa pour la création des disques
srand((unsigned)time(NULL));
// On crée quelques disques pour essayer les algos
vector<Disque> tabDisque;
for (int i=0; i < 10; ++i) {
tabDisque.push_back(Disque(rand() % 10 + 1, Point(rand() % 30 + 1, rand() % 30 + 1)));
}
// On récupère la taille du vector
int const taille = (const int)tabDisque.size();
tri_fusion(0, taille-1, tabDisque, taille);
for (int z = 0; z < taille ; z++) {
cout << tabDisque[z].getPoint().getX() - tabDisque[z].getRayon() << " ";
}
return 0;
}
Thanks a lot and sorry for the french code :)
Upvotes: 1
Views: 375
Reputation: 26
If you are aware of the difference between passing things to a function "by reference" and "by value": You passed your vector by value, you should clearly pass it by reference so you can modify it.
If not: The way you pass you vector to your function right now is called passing "by value". The function will receive a copy of the vector. Now if you modify this copy, say by swapping two entries, the original vector will be unchanged. What you need to do is pass the function a reference to the vector so you can modify it. To do so, change vector<Disque> tableau
to vector<Disque> &tableau
both in fusion
and tri_fusion
. You should look up the difference between these two ways to pass values to functions, it's quite important.
A second mistake is
for(k = indice_bas; k <= indice_haut; k++){
tableau[k] = tab_tmp[k];
}
The indexing in tab_tmp
starts at 0
, as opposed to indice_bas
for tableau
. You need to change this to something like
for(k = 0; k <= indice_haut-indice_bas; k++){
tableau[k+indice_bas] = tab_tmp[k];
}
This are the only mistakes I can see right now, but I can't compile your code as I don't know what Disque
is, so there might be more I have missed.
Upvotes: 1
Reputation: 1131
Your variable tabDisque
gets passed to your fusion()
-function, but it does not get returned. So it stays the same way how you input it there. One solution would be passing pointers instead.
Change the signature of your function to:
void fusion(int indice_bas, int milieu, int indice_haut, vector<Disque> *tableau)
Any access to tableau
variable would need to be dereferenced. E.g. (*tableau)[h]
and pass a reference pointer like this:
tri_fusion(0, taille-1, &tabDisque, taille);
(This is assuming your algorithm works correctly)
Upvotes: 1