begin process at 2012 05 27 18:39:28
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Maths & Algorithmes

 > MERGE SORT

MERGE SORT


 Information sur la source

Note :
Aucune note
Catégorie :Maths & Algorithmes Niveau :Débutant Date de création :20/02/2005 Date de mise à jour :21/02/2005 17:52:11 Vu :4 586

Auteur : dominion

Ecrire un message privé
Site perso
Ce membre participe au partage de revenus publicitaires
Commentaire sur cette source (14)
Ajouter un commentaire et/ou une note


 Description

Ce code est un Merge Sort. Il permet de trier un tableau par séparations successives. Son intérêt est sa rapidité. Pour plus d'infos voyez sur google ou wikipédia c'est très bien expliqué.

Source

  • template <class T> void MergeSort(T *t, signed long int beg, signed long int end)
  • {
  • //Si la section est de 1 ou 2 champs ==> check si en ordre et fin du tri
  • if ((end - beg) < 2)
  • {
  • if (t[beg] > t[end])
  • {
  • T temp = t[end];
  • t[end] = t[beg];
  • t[beg] = temp;
  • }
  • }
  • //Fin section d'un ou 2 champs
  • //> 2 champs ==> lance le tri (effet de récurrence) et rassemble
  • else
  • {
  • //Définition des nouvelles valeurs de début et de fin
  • signed long int newend = (beg + end) >> 1;
  • signed long int newbeg = newend + 1;
  • //Fin Définition des nouvelles valeurs de début et de fin
  • MergeSort(t, beg, newend);
  • MergeSort(t, newbeg, end);
  • //Rassemblement des section séparée et tri
  • ++newend;
  • ++end;
  • for (signed long int i = beg; i < newend; ++i)
  • for (signed long int j = newbeg; j < end; ++j)
  • {
  • if (t[i] <= t[j])
  • break;
  • //Décalage
  • T temp = t[j];
  • for (signed long int k = j; k > i; --k)
  • t[k] = t[k - 1];
  • t[i] = temp;
  • ++i; //Vu le décalage, l'indice de la nouvelle valeur est à augmenter
  • ++newend; //Vu le décalage, la fin du premier est plus loin
  • ++newbeg; //Vu le décalage, le début du deuxième est plus loin
  • //Fin Décalage
  • }
  • //Fin Rassemblement des section séparée et tri
  • }
  • //Fin > 2 champs
  • }
  • //-------------------------------------------------------------------------------------------------
  • int main()
  • {
  • srand(clock());
  • int n;
  • cout << "Entrer la taille du tableau initial : "; cin >> n;
  • cout << "\n";
  • int *t = new int[n];
  • for(int i = 0; i < n; i++)
  • {
  • t[i] = (rand()%50)-10;
  • cout << t[i] << ' ';
  • }
  • cout << endl;
  • MergeSort(t, 0, n - 1);
  • for(int i = 0; i < n; i++)
  • cout << t[i] << ' ';
  • delete t;
  • return 0;
  • }
template <class T> void MergeSort(T *t, signed long int beg, signed long int end)
{
 //Si la section est de 1 ou 2 champs ==> check si en ordre et fin du tri
   if ((end - beg) < 2)
   { 
    if (t[beg] > t[end])
    {     
     T temp = t[end];
     t[end] = t[beg];
     t[beg] = temp;
    }
   } 
 //Fin section d'un ou 2 champs
 
 //> 2 champs ==> lance le tri (effet de récurrence) et rassemble
   else
   {
    //Définition des nouvelles valeurs de début et de fin
      signed long int newend = (beg + end) >> 1;
      signed long int newbeg = newend + 1;
    //Fin Définition des nouvelles valeurs de début et de fin
    MergeSort(t, beg, newend);
    MergeSort(t, newbeg, end);
    
    //Rassemblement des section séparée et tri
      ++newend;
      ++end;
      
      for (signed long int i = beg; i < newend; ++i)
       for (signed long int j = newbeg; j < end; ++j)
       {
        if (t[i] <= t[j])
         break;
         
        //Décalage 
          T temp = t[j];        
        
          for (signed long int k = j; k > i; --k)
           t[k] = t[k - 1];           
          t[i] = temp;
          
          ++i;      //Vu le décalage, l'indice de la nouvelle valeur est à augmenter
          ++newend; //Vu le décalage, la fin du premier est plus loin
          ++newbeg; //Vu le décalage, le début du deuxième est plus loin
        //Fin Décalage     
       } 
    //Fin Rassemblement des section séparée et tri
   } 
 //Fin > 2 champs
} 
//-------------------------------------------------------------------------------------------------

int main()
{
 srand(clock());
 int n;
 cout << "Entrer la taille du tableau initial : "; cin >> n;
 cout << "\n";

 int *t = new int[n]; 
 for(int i = 0; i < n; i++)
 {
  t[i] = (rand()%50)-10;
  cout << t[i] << ' ';
 } 
 cout << endl;

 MergeSort(t, 0, n - 1);
 
 for(int i = 0; i < n; i++)
  cout << t[i] << ' ';

 delete t; 
 return 0;
}

 Conclusion

Cet algo est une fonction récursive. Pour plus d'infos voyez le zip.
La partie de rassemblement de 2 morceaux peut être accélérée. J'y travaille actuellement.


 Historique

21 février 2005 17:52:11 :
Petites amélioréation effectuées, mais san grande importance.

 Sources du même auteur

Source avec Zip PARSER QUI SE VEUT GÉNÉRIQUE
Source avec Zip CRÉATEUR DE FICHIER LIB

 Sources de la même categorie

Source avec Zip UN EXAMPLE D'APPLICATION EN CUDA DE L'ALGORITHME DE SCAN POU... par oguzaras
Source avec Zip Source avec une capture CHIFFREMENT DE VIGENERE par lajouad
Source avec Zip Source avec une capture ANALYSE SYNTAXIQUE par lajouad
Source avec Zip Source avec une capture STRUCTURE D'UNE MATRICE PAR LES LISTE LINÉAIRE (NON CONTUGUS... par benzarabel
Source avec Zip Source avec une capture DESSINER UNE ARBRE BINAIRE( MODE CONSOLE): par benzarabel

Commentaires et avis

Commentaire de BruNews le 21/02/2005 00:02:43 administrateur CS

Pour vraiment accélérer le traitement, faudrait supprimer la récurrence.

Commentaire de dominion le 21/02/2005 00:08:30

C'est vrai aussi, mais c'est plus lisible comme ça... Libre à toi de recoder sans récurrence, je ne pense pas que cela soit difficile.

Commentaire de BruNews le 21/02/2005 00:11:15 administrateur CS

C'est livré avec le compilo, ça s'appelle qsort().

Commentaire de dominion le 21/02/2005 00:16:35

Ce code a un but purement pédagogique... Il est clair qu'il existe des algos de tri plus efficaces, mais il peut permettre à certains de mieux comprendre le merge sort. C'est tout...

Commentaire de steve_clamage le 21/02/2005 00:34:18

on peux supprimer la récurence et dérouler le code avec les templates, seulement la taille du tableau devra etre connue à la compilation

Commentaire de Kirua le 21/02/2005 07:55:42

Et ça va exploser la taille de l'exe, merci bien :/ Autant rester générique. Et puis très bien il y a des algos de tri fournis: mais si un jour il doit coder avec un langage qui n'a pas ça en bibliothèque standard, faudra bien qu'il mette la main à la patte, et ça risque d'être meilleur avec un merge sort n log n qu'avec un bubble sort n².

Quoique, l'histoire de récursivité ça me chagrine qd même, c'est notoirement un procédé lent ... à revoir, quitte à garder une version récursive pour benchmark et lisibilité.

Commentaire de steve_clamage le 21/02/2005 08:23:24

il me semble qu'il y a aussi des techniques pour simuler la récursivité avec sa propre pile mais je sais pas ce que ca vaut

Commentaire de vecchio56 le 21/02/2005 11:11:16 administrateur CS

Dans la boucle de fusion:
for (signed long int i = beg; i < newend; ++i)
  for (signed long int j = newbeg; j < end; ++j)
  {
    if (t[i] <= t[j]) break; ...

si le tableau est déja trié par exemple, on va a chque fois dans le break, et du coup les deux for font n/2 itérations, donc rien que la fusion est en n^2, alors que cet algo est censé être en n log2 n. (Je fais confiance à Kirua)
Soit je me trompe, soit la mise en ouvre n'est pas bonne...

Commentaire de BruNews le 21/02/2005 11:13:49 administrateur CS

steve_clamage > c'est exact ce que fait qsort(), la récursion est simulée par une stack interne à la procédure, c'est d'une efficacité redoutable.

Ceci dit, on ne remet pas en cause le coté didactique de cette source, c'est impec pour montrer l'emploi des template.

Commentaire de dominion le 21/02/2005 17:25:17

vecchio56 : si le break est là, c'est justement pour éviter le n² ! Regarde :

(6, 2, 3, 5, 4, 8)
Je pars du principe qu'on a déjà fait le début. On en est à
(2, 3, 6), (4, 5, 8)
qui sont deux tableaux triés distincts (c'est une vue de l'esprit, ils sont tous les deux stockés dans t). Mon code passe 3 fois dans le premier tableau, et teste la premiere valeur du deuxième tableau. Ce qui donne :

2 < 4 ==> OUI, donc break;
3 < 4 ==> OUI, idem que pour 2 < 4
6 < 4 ==> NON, on décale donc le 6 de 1 vers la droite pour laisser la place au 4 qu'on intègre au premier tableau, ce qui donne : (2, 3, 4, 6), (5, 8)
6 < 5 ==> NON, idem que pour 6 < 4 : (2, 3, 4, 5, 6), (8)
6 < 8 ==> OUI, donc break;
Il n'y a plus rien après 6 dans le premier tableau, c'est donc trié. Total : 5 tests. C'est le plus que j'ai trouvé. C'est optimisable en prenant au centre du tableau au début, je pense... Mais je n'ai pas encore eu l'occasion de vérifier.

Commentaire de steve_clamage le 21/02/2005 19:08:25

Merci pour cette precision BruNews, si qsort fais comme ca montre que les algos récursif mérite biens qu'on les étudies, ca peux toujours etre une solution.

Commentaire de dominion le 21/02/2005 19:18:56

BruNews : que veux-tu dire par simulé ?

Commentaire de BruNews le 21/02/2005 19:56:22 administrateur CS

On crée un tableau de pointeurs qui est la simulation des params (adresses) dans la récursion mais il n'y a pas d'empilage dépilage.

Commentaire de vecchio56 le 22/02/2005 18:23:56 administrateur CS

dominion> ok, c'est que je n'ai pas l'habitude de voir des  break comme ca, je me suis trompé

 Ajouter un commentaire




Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,468 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales