#include #include #include const int bavard=0; int *allocation(int taille) { return malloc(taille*sizeof(int)); } void remplir_tableau(int *t, int n, int min, int max) { while(n) t[--n]=min+rand()%(max-min+1); } void afft(int *t,int n) { while(n--) printf("%d ",*t++); printf("\n"); } void afft10(int*t,int n) { afft(t,n<10?n:10); } int est_trie(int *t, int n) { while(--n>0) if(t[n]x;j--) t[j]=t[j-1]; } void tri_bulle(int*t,int n) { int i,k,x;// k est la position du dernier élément déplacé. for(;n>1;n=k) // Tant qu'il y a plusieurs nombres à trier for(i=k=1;i>1)>>l&255; // m est inutile si *t n'est pas signé. for(j=0;j<256;j++) e[j]=0; // mise à 0 des 256 compteurs for(i=0;i>l&255]++; // comptage for(c=n,j=256;j--;) e[j^m]=c-=e[j^m]; // empilage des seaux for(i=0;i>l&255]++]=t[i];// tri stable selon un chiffre v=u,u=t,t=v; // t et tt sont échangés.(sizeof(int) est pair) } } void tri_comptage(int*t,int n) { if(n<2) return; int i, j, min=*t, max=*t; for(i=1;imax) max=t[i]; int l=max-min+1, c[l], k=0; for(j=0;jmax) max=t[i]; int l=max-min+1, c[l]; for(j=0;ji) // qui n'a pas encore été mis à sa place do y=t[j=--c[x-min]], t[j]=x, x=y; while(j!=i); // débute un cycle de permutations. } void tri_bingo(int*t, int n) { while(n>1) { int m=*t, i; for(i=1;im) m=t[i]; // m est la plus grande valeur du tableau for(i=n;i;) if(t[--i]==m) t[i]=t[--n],t[n]=m; // Tous les m sont mis à la fin } } int Partition(int*t,int j) { int i=j/2, p=t[i]; // On prend le pivot au milieu. for(t[i]=*t,*t=p,i=0;;)// On l'échange avec le premier élément. { while(t[--j]>p) ; // Un petit élément en fin de tableau if(i==j) return i; t[i]=t[j], t[j]=p; // est échangé avec le pivot. while(t[++i]1;n=p) p=Partition(t,n),tri_rapide(t+p+1,n-p-1); } void tri_rapid(int*t,int n)// ne trie pas les petits sous-tableaux { for(int p;n>5;n=p) p=Partition(t,n),tri_rapid(t+p+1,n-p-1); } void tri_rapi(int*t,int n) { tri_rapid(t,n),tri_insertion(t,n); } void Fusion(int*t,int n,int m) { int u[n], *v=t+n, i, j, k; // t[n+m]=t[n]+v[m] for(i=0;i=f) return; int m=(d+f)/2; merge_sort(tab,d,m); merge_sort(tab,m+1,f); fusion(tab,d,m,f); } void tri_merge(int*t,int n) { merge_sort(t,0,n-1); } int croi=0; // croi=1 si le tableau tend à croitre void fusi(int*t,int n,int m) // recherche dichotomique { if(!croi) return Fusion(t,n,m); // éventuelle if(!n || !m) return; // du premier t[i] qui doit bouger int i=0, j, k=n, x=t[n]; // pour minimiser n while(ix) k=j; else i=j+1; Fusion(t+i,n-i,m); } void tri_fusion(int*t,int nm) { if(nm<6) return tri_insertion(t,nm); int n=nm/2, m=nm-n, *v=t+n; tri_fusion(t,n); // trie la première moitié tri_fusion(v,m); // trie la deuxième moitié fusi(t,n,m); // fusionne les 2 moitiés déjà triées } int min(int a,int b) { return at[j]) ; // Une suite décroissante retourne(t+*p,t+j); // est retournée puis while(jz||x>y||(j==n&&xz) fusi(t+p[3],z,y), p[2]=p[1], *++p=j; else fusi(t+p[2],y,x), *++p=j; } } /* La procédure précédente utilise une pile contenant des "runs". Soient x, y et z les longueurs des 3 runs au sommet de pile. (x est au sommet). On doit avoir x<=y<=z et x+y<=z. Sinon on fusionne y avec min(x,z). Mais la pile va peut-être croitre et certains runs vont fusionner. Donc x et y vont peut-être augmenter et on n'aura plus x+y<=z. On peut modifier la procédure pour éviter cela. La procédure suivante utilise deux piles. La première pile est le bas de l'ancienne pile. Trois runs consécutifs de cette pile vérifient toujours x+y<=z et x<=y. La deuxième pile est le haut de l'ancienne pile. On essaye de transférer son sommet dans la première pile : *--p=j=*--q. Les deux piles sont aux deux extrémités du tableau pile[]. Dans la pile on ne met pas la longueur d'un run mais l'indice de l'élément suivant le run et j=*p est une copie du sommet de pile. Donc x=p[0]-p[1], y=p[1]-p[2], ... . */ void tri_tim2(int *t, int n) { int pile[100], *q=pile, *p=q+100, j, x, y, z; for(*--p=-3*n, *--p=-n, *--p=j=0;jt[j]) ; // Une suite décroissante retourne(t+*p,t+j); // est retournée puis while(jpile;) // et mise dans la pile. for(*--p=j=*--q;x=j-p[1],y=p[1]-p[2],z=p[2]-p[3],x+y>z||x>y||(j==n&&xz) fusi(t+p[3],z,y), *q++=j, j=*++p; else fusi(t+p[2],y,x); } } void tri_tas(int*t,int n) { int i,j,x,s=n/2; for(;n>1;t[i]=x,s-=!s? x=*t,*t=t[--n],t[n]=x,0 :1) for(x=t[i=s];j=2*i+1,jt[j]]>x;i=j) t[i]=t[j]; } void peigne(int*t,int n) { int h,i,j,x; for(h=n;h=h*10/13,h>1;) for(j=h;jt[j]) x=t[i],t[i]=t[j],t[j]=x; } void tri_peigne(int*t,int n) {peigne(t,n),tri_bulle(t,n);} void tri_peign (int*t,int n) {peigne(t,n),tri_insertion(t,n);} void tri_shell_pratt(int*t,int n) { for(int h=n;h;h--) if(729*729*729%(h/(h&-h))==0) // si h=(2^a)*(3^b) for(int i=0,j;j=i+h,jt[j]) { int x=t[i]; t[i]=t[j], t[j]=x; } } void tri_stooge(int*t, int n) { if(n>2) { int m=2*(n+1)/3; tri_stooge(t,m),tri_stooge(t+n-m,m),tri_stooge(t,m); } else if(n>1 && *t>t[1]) { int x=*t; *t=t[1], t[1]=x; } } void melange_aleatoire(int*t, int n) { while(n>1) {int j=rand()%n, x=t[--n]; t[n]=t[j], t[j]=x; }} void tri_aleat(int*t, int n) { while(!est_trie(t,n)) melange_aleatoire(t,n); } void ech(int*a,int*b) { int x=*a; *a=*b; *b=x;} void tri_bete(int*t,int n) { int ok=0; void tri(int m) { if(m<=1) ok=est_trie(t,n); else for(int j=m--;j-- && !ok;) ech(t+m,m&1?t:t+j), tri(m); } tri(n); } typedef void tri_t(int*,int); void test_tri(int*t, int*u, int*ut, int n, tri_t tri,char*nom) { if(bavard) afft10(t,n); for(int i=0;it[i+1]) x=t[i],t[i]=t[i+1],t[i+1]=x, i--; else i++; } } void tri_shaker(int*t,int n) { int m=0, k=n-1, i, x; while(mm;i--) if(t[i]t[i+1]) x=t[i],t[k=i]=t[i+1],t[i+1]=x; } } #define nom(tri_truc) tri_truc,#tri_truc // tri_chose,"tri_chose" int main() { srand(time(0)); for(int niv=3;niv--;) for(int n=10;n<=1000000;n*=10) { int *t=allocation(n*3), *u=t+n, *v=u+n, i;// int t[n],u[n],v[n]; if(niv==2) for(i=0;i