按矢量中的对象属性合并排序

Merge sort by object attribute in vector

本文关键字:属性 合并 排序 对象      更新时间:2023-10-16

我做了一个c++项目来比较不同的算法复杂性。我有一个圆vector<Disque>的向量,我想根据圆的属性x对这个向量进行排序(左边的x轴最多=>x轴半径)。我已经实现了合并排序算法,但不起作用,也不知道为什么。

合并排序实现:

/**
* 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;
}

非常感谢并为法语代码感到抱歉:)

如果你知道"通过引用"answers"通过值"向函数传递东西之间的区别:你通过值传递向量,你应该清楚地通过引用传递它,这样你就可以修改它。

如果不是:现在将向量传递给函数的方式称为"按值传递"。函数将接收矢量的副本。现在,如果修改这个副本,比如说通过交换两个条目,原始向量将保持不变。您需要做的是向函数传递对向量的引用,以便对其进行修改。为此,请在fusiontri_fusion中将vector<Disque> tableau更改为vector<Disque> &tableau。您应该查找这两种向函数传递值的方法之间的差异,这非常重要。

第二个错误是

for(k = indice_bas; k <= indice_haut; k++){
tableau[k] = tab_tmp[k];
}

tab_tmp中的索引从0开始,与tableauindice_bas相反。你需要将其更改为类似的内容

for(k = 0; k <= indice_haut-indice_bas; k++){
tableau[k+indice_bas] = tab_tmp[k];
}

这是我现在能看到的唯一错误,但我不能编译你的代码,因为我不知道Disque是什么,所以我可能错过了更多。

变量tabDisque被传递给fusion()-函数,但不会返回。所以它和你在那里输入的一样。一种解决方案是传递指针。

将函数的签名更改为:

void fusion(int indice_bas, int milieu, int indice_haut, vector<Disque> *tableau)

tableau变量的任何访问都需要取消引用。例如(*tableau)[h]

并传递这样的参考指针:

tri_fusion(0, taille-1, &tabDisque, taille);

(这是假设你的算法工作正常)