StanOfSky
Messages postés43Date d'inscriptionmardi 30 mars 2004StatutMembreDernière intervention 7 octobre 2006 15 juil. 2004 à 23:54
ba de toute maniere ca existe po la récursivité en info d'un point de vu purement physique... c juste une écriture plus lisible et plus facile à démontrer d'un point de vu mathématique.
en fait au résultat c du linéaire : t'empiles, tu dépiles...
apres tu peu avoir des compilo qui optimisent à fond et optenir le meme résultat en ayant ecrire une fonction récursive qu'en l'ayant déroulé et fait tout meme le systeme de pile.
seul l'assembleur reste la meilleur solution pour etre certain d'avoir une fonctions optimisée a fond ;)
Maegis
Messages postés101Date d'inscriptionvendredi 15 février 2002StatutMembreDernière intervention 6 août 2007 15 juil. 2004 à 13:07
Je parle bien d'option info, c'est a dire un petit programme, peu d'heures de cours et des profs qui ne connaissent que le programme et pas grand chose à coté.
Et si tu regardes les commentaires des codes sources tu remarquera qu'il y en a quelques uns du genre : "ah oui je savais pas, mon prof d'info m'a dit le contraire"
Et merci pour l'info, je vais de ce pas acheter 1 bon livre d'algorithmique, je vais voir si je trouve un de ses bouquins
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 15 juil. 2004 à 12:35
Je n'irais pas jusque la (encore que...) mais faut surtout plusieurs sources d'informations. Je te conseille Robert Sedgewick qui est une reference absolue.
Maegis
Messages postés101Date d'inscriptionvendredi 15 février 2002StatutMembreDernière intervention 6 août 2007 15 juil. 2004 à 12:22
Conclusion : ne pas croire les profs d'option info
On m'avait affirmé qu'on ne pouvait pas """"supprimer la recursivité"""" dans le qsort sans deteriorer les performances
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 15 juil. 2004 à 00:25
on est bien d'accord !!!
cs_djl
Messages postés3011Date d'inscriptionjeudi 26 septembre 2002StatutMembreDernière intervention27 novembre 20047 15 juil. 2004 à 00:17
oui, mais en fait j'ai laissé comme ca car on a toujoursl a possibilité de specifier les fonctions swap_i et min_i inline (en c99) ce qui reviendrai au meme
la j'ai tenu à faire un code c ansi et clair, mais c'est sur que pour la performance il vaut mieux derouler le code ou specifier les fonctions inline
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 15 juil. 2004 à 00:15
http://www.cppfrance.com/code.aspx?ID=11151 c'est exemple ou j'ai devie le qsort de la CRT pour tout faire en interne. Juste que la il trie plus qu'un simple tableau de int, on peut donc beaucoup reduire le code de tri.
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 15 juil. 2004 à 00:12
djl > essaie de tout mettre dans la meme fonction pour qu'il n'y ait pas d'appels et d'empilage de params.
cs_djl
Messages postés3011Date d'inscriptionjeudi 26 septembre 2002StatutMembreDernière intervention27 novembre 20047 15 juil. 2004 à 00:03
j'ai repris le meme algo de la methode sort() de ma classe matrice
cs_djl
Messages postés3011Date d'inscriptionjeudi 26 septembre 2002StatutMembreDernière intervention27 novembre 20047 15 juil. 2004 à 00:02
comme ca c'est efficace aussi ?
void swap_i(int *i1, int *i2)
{
int i = *i1;
*i1 = *i2;
*i2 = i;
}
size_t min_i(int *v, size_t size)
{
int min *v, *p v;
size_t i 0, ind_min 0;
while( ++i < size )
if( *(++p) < min )
{
min = *p;
ind_min = i;
}
for( i = 0; i < size; i++, p++)
swap_i( p, p + min_i(p, size - i) );
}
par exemple
int v[]={1,3,6,5,9,2,7,45,45564,545,54,1,5,26,54,74,5215,54};
sort_i(v, sizeof v / sizeof *v );
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 14 juil. 2004 à 23:41
Robert Sedgewick explique la suppression de la recursivite (comme dit plus haut) a partir de la page 128 de: "Algorithmes en langage C".
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 14 juil. 2004 à 23:37
pas du tout, tu trouves exemple dans le qsort de la crt, on simule le recursif par une remontee dans le code grace a une stack implementee en local.
Maegis
Messages postés101Date d'inscriptionvendredi 15 février 2002StatutMembreDernière intervention 6 août 2007 14 juil. 2004 à 23:27
>>>Cyberboy
Il ne faut pas faire la comparaison avec un quicksort, ici tu as plein d'indications supplementaires dont le fait que les nombres sont tous positifs et plus petits que d
La donnée de d permet d'optimiser la fonction de tri
Les algos de quicksort, de heapsort ou de tri fusion sont optimum pour la seule donnée de la taille du tableau et le tableau lui-même. Avec des indications supplementaires on peut faire beaucoup mieux et on peut avoir des tris linéaires (en O(n)) plutôt que des quasi-linéaires (en O(n*ln(n)) )
>>>>>ekinoks
Ta fonction ne trie pas le tableau, si on décide de ne pas afficher les valeurs ton prog ne fait aucune opération sur tab2
Si on affiche les results, tu les affiches et c'est tout, à la fin le tableau tab 2 n'est pas trié
int main(int argc, char *argv[])
{
DWORD deb, fin;
int i,j,k;
int* tmp;
int nbchiffres;
int max;
int *tab,*tab2;
printf("Nombre de chiffres a classer ?");
scanf("%i", &nbchiffres);
printf("Nombres allant de 0 a ?");
scanf("%i", &max);
//alloc
tab = new int[nbchiffres];
tab2 = new int[max];
for (i=0;i<nbchiffres;i++) //Inscrit des nombres aleatoirement
tab[i]=(rand()%max);
ZeroMemory(tab2,max); //on init tout a zero
deb = GetTickCount();
for (i=0;i<nbchiffres;i++)
tab2[tab[i]]++; //on compte le nb de fois que chaque nombre apparait
tmp = tab; //on sauve le pointeur
for (i=0;i<max;i++) //on recompose le tableau
{
k = tab2[i];
for (j=0;j<k;j++)
{
*tab=i;
tab++;
}
}
tab = tmp; //on restaure
fin = GetTickCount(); //fin du crono
printf("Le tri a mis %d Ms\n", fin - deb);
delete[] tab;
delete[] tab2;
system("pause");
return 0;
}
voila cette fonction trie un tab de 1.000.000 , 1.000.000 en 30ms chez moi et le qsort de la stdlib met 60ms
>>>>>BruNews
Le quicksort est forcement recursif !!!!
Il applique la méthode diviser pour regner :
On coupe le tableau en 2 selon le pivot (1ere moitié contenant les cases plus petites que le pivot, 2eme moitié le reste) et on appelle recursivement le programme sur les deux morceaux de tableau ainsi obtenus
C'est du recursif pur, qui dit diviser pour regner dit recursif.
Quoi qu'il en soit le quicksort est un bon algo dans la moyenne ( O(N*ln(N) ) bien que dans le pire des cas on atteigne une complexité en O(N^2)
Sinon il y a toujours le tri par tas (heapsort) qui est toujours en O (N*ln(N))
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 14 juil. 2004 à 22:10
C'est sur qu'un quicksort ne doit jamais etre recursif sinon il ne restera que le 'sort' mais ne sera plus 'quick' du tout. Toute fonction recursive est plus lente que la version iterative pour cause d'empilage des params a chaque tour.
Cyberboy2054
Messages postés173Date d'inscriptionjeudi 20 décembre 2001StatutMembreDernière intervention22 août 2008 14 juil. 2004 à 21:54
C' est plutôt bon comme resultat. Mon implementation de quicksort, bien qu' étant simpliste et recursive, met 10 fois plus de temps dans les memes conditions.
Est il possible de dérécursifier quicksort, ou y-a-t' il des moyens de l'optimiser (genre une methode rapide pour trouver un bon pivot) ?
cs_djl
Messages postés3011Date d'inscriptionjeudi 26 septembre 2002StatutMembreDernière intervention27 novembre 20047 14 juil. 2004 à 19:02
ekinoks > tu devrai isoler ta methode de tri dans une fonction, ca sera plus facile de comparer (et plus reutilisable)
int *isort(int *tab,size_t size);
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 14 juil. 2004 à 19:02
Comme on te l'a fait remarquer plus haut, ton code ne compiler jamais. Faut une alloc dynamique.
Rectif attendue, merci.
BruNews, Admin CS, MVP Visual C++
cs_djl
Messages postés3011Date d'inscriptionjeudi 26 septembre 2002StatutMembreDernière intervention27 novembre 20047 14 juil. 2004 à 18:58
en c ca gueule avec -ansi -pedantic pour etre sur que c'est ansi, avant const ca n'existait meme pas
BlackGoddess
Messages postés338Date d'inscriptionjeudi 22 août 2002StatutMembreDernière intervention14 juin 2005 14 juil. 2004 à 18:49
int tab [2][d]; >> tu compiles avec quel compilateur ?
normalement la taille d'un tableau DOIT être résolue a la compilation, hors la il est impossible de la connaître, puisque d est une saisie utilisateur (a l'execution donc).
15 juil. 2004 à 23:54
en fait au résultat c du linéaire : t'empiles, tu dépiles...
apres tu peu avoir des compilo qui optimisent à fond et optenir le meme résultat en ayant ecrire une fonction récursive qu'en l'ayant déroulé et fait tout meme le systeme de pile.
seul l'assembleur reste la meilleur solution pour etre certain d'avoir une fonctions optimisée a fond ;)
15 juil. 2004 à 13:07
Et si tu regardes les commentaires des codes sources tu remarquera qu'il y en a quelques uns du genre : "ah oui je savais pas, mon prof d'info m'a dit le contraire"
Et merci pour l'info, je vais de ce pas acheter 1 bon livre d'algorithmique, je vais voir si je trouve un de ses bouquins
15 juil. 2004 à 12:35
15 juil. 2004 à 12:22
On m'avait affirmé qu'on ne pouvait pas """"supprimer la recursivité"""" dans le qsort sans deteriorer les performances
15 juil. 2004 à 00:25
15 juil. 2004 à 00:17
la j'ai tenu à faire un code c ansi et clair, mais c'est sur que pour la performance il vaut mieux derouler le code ou specifier les fonctions inline
15 juil. 2004 à 00:15
c'est exemple ou j'ai devie le qsort de la CRT pour tout faire en interne. Juste que la il trie plus qu'un simple tableau de int, on peut donc beaucoup reduire le code de tri.
15 juil. 2004 à 00:12
15 juil. 2004 à 00:03
15 juil. 2004 à 00:02
void swap_i(int *i1, int *i2)
{
int i = *i1;
*i1 = *i2;
*i2 = i;
}
size_t min_i(int *v, size_t size)
{
int min *v, *p v;
size_t i 0, ind_min 0;
while( ++i < size )
if( *(++p) < min )
{
min = *p;
ind_min = i;
}
return ind_min;
}
void sort_i(int *v, size_t size)
{
size_t i;
int *p = v;
for( i = 0; i < size; i++, p++)
swap_i( p, p + min_i(p, size - i) );
}
par exemple
int v[]={1,3,6,5,9,2,7,45,45564,545,54,1,5,26,54,74,5215,54};
sort_i(v, sizeof v / sizeof *v );
14 juil. 2004 à 23:41
14 juil. 2004 à 23:37
14 juil. 2004 à 23:27
Il ne faut pas faire la comparaison avec un quicksort, ici tu as plein d'indications supplementaires dont le fait que les nombres sont tous positifs et plus petits que d
La donnée de d permet d'optimiser la fonction de tri
Les algos de quicksort, de heapsort ou de tri fusion sont optimum pour la seule donnée de la taille du tableau et le tableau lui-même. Avec des indications supplementaires on peut faire beaucoup mieux et on peut avoir des tris linéaires (en O(n)) plutôt que des quasi-linéaires (en O(n*ln(n)) )
>>>>>ekinoks
Ta fonction ne trie pas le tableau, si on décide de ne pas afficher les valeurs ton prog ne fait aucune opération sur tab2
Si on affiche les results, tu les affiches et c'est tout, à la fin le tableau tab 2 n'est pas trié
--------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int main(int argc, char *argv[])
{
DWORD deb, fin;
int i,j,k;
int* tmp;
int nbchiffres;
int max;
int *tab,*tab2;
printf("Nombre de chiffres a classer ?");
scanf("%i", &nbchiffres);
printf("Nombres allant de 0 a ?");
scanf("%i", &max);
//alloc
tab = new int[nbchiffres];
tab2 = new int[max];
for (i=0;i<nbchiffres;i++) //Inscrit des nombres aleatoirement
tab[i]=(rand()%max);
ZeroMemory(tab2,max); //on init tout a zero
deb = GetTickCount();
for (i=0;i<nbchiffres;i++)
tab2[tab[i]]++; //on compte le nb de fois que chaque nombre apparait
tmp = tab; //on sauve le pointeur
for (i=0;i<max;i++) //on recompose le tableau
{
k = tab2[i];
for (j=0;j<k;j++)
{
*tab=i;
tab++;
}
}
tab = tmp; //on restaure
fin = GetTickCount(); //fin du crono
printf("Le tri a mis %d Ms\n", fin - deb);
delete[] tab;
delete[] tab2;
system("pause");
return 0;
}
voila cette fonction trie un tab de 1.000.000 , 1.000.000 en 30ms chez moi et le qsort de la stdlib met 60ms
>>>>>BruNews
Le quicksort est forcement recursif !!!!
Il applique la méthode diviser pour regner :
On coupe le tableau en 2 selon le pivot (1ere moitié contenant les cases plus petites que le pivot, 2eme moitié le reste) et on appelle recursivement le programme sur les deux morceaux de tableau ainsi obtenus
C'est du recursif pur, qui dit diviser pour regner dit recursif.
Quoi qu'il en soit le quicksort est un bon algo dans la moyenne ( O(N*ln(N) ) bien que dans le pire des cas on atteigne une complexité en O(N^2)
Sinon il y a toujours le tri par tas (heapsort) qui est toujours en O (N*ln(N))
14 juil. 2004 à 22:10
14 juil. 2004 à 21:54
Est il possible de dérécursifier quicksort, ou y-a-t' il des moyens de l'optimiser (genre une methode rapide pour trouver un bon pivot) ?
14 juil. 2004 à 19:02
int *isort(int *tab,size_t size);
14 juil. 2004 à 19:02
Rectif attendue, merci.
BruNews, Admin CS, MVP Visual C++
14 juil. 2004 à 18:58
14 juil. 2004 à 18:49
normalement la taille d'un tableau DOIT être résolue a la compilation, hors la il est impossible de la connaître, puisque d est une saisie utilisateur (a l'execution donc).