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

时间:2017-01-28 23:48:54

标签: c++ vector mergesort

我制作一个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);
    }
}

主要:

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

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

2 个答案:

答案 0 :(得分:1)

您的变量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);

(假设您的算法正常运行)

答案 1 :(得分:1)

如果您知道将事物传递给函数&#34;通过引用&#34; &#34;按值&#34;:你按值传递了矢量,你应该通过引用清楚地传递它,这样你就可以修改它。

如果不是:您现在将向量传递给函数的方式称为传递&#34;按值&#34;。该函数将接收向量的副本。现在,如果您修改此副本,例如通过交换两个条目,原始向量将保持不变。你需要做的是传递函数对向量的引用,以便你可以修改它。为此,请在vector<Disque> tableauvector<Disque> &tableau中将fusion更改为tri_fusion。你应该查看这两种方法之间的差异,将值传递给函数,这非常重要。

第二个错误是

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

tab_tmp中的索引编号从0开始,而indice_bas则为tableau。您需要将其更改为

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

这是我现在唯一能看到的错误,但我无法编译您的代码,因为我不知道Disque是什么,所以可能会有更多错过。< / p>