#include #include #include #include #include template inline void swap(T &a, T &b) { T t = a; a = b; b = t; } template inline void insert(T *l, T *r, int (*compar)(const void*, const void*)) { T* s = l; while (s l && compar(k,k-1) < 0) { swap(*k, *(k-1)); --k; } ++s; } } #define INS 12 template void secret1(T *l, T *r, int (*compar)(const void*, const void*)) { T *j = r; T *i = l+1; { int a = compar(l, l+1), b= compar(l,l+2), c = compar(l+1,l+2); if (a > 0) { if (b > 0) if (c<0) swap(*l,l[2]); else swap(*l,l[1]); } else if (a < 0) { if (b < 0) if (c<0) swap(*l,l[1]); else swap(*l,l[2]); } } while (i <= j) { int a = compar(l,i); if (a <= 0) { int b = 0; while (j > l && (b = compar(l,j)) < 0) --j; if (j > i) { if (a != b) { swap(*j, *i); --j; } else { --i; --j; } } else break; } else { ++i; } } swap(*l, *j); --j; //std::cout<< j-l <<" " << r-i << std::endl; if (l+INS < j) secret1(l,j, compar); else insert(l,j,compar); if (i+INS < r) secret1(i,r, compar); else insert(i,r,compar); } inline void swapsize(char *a,char *b, size_t size) { for (int cnt = 0; cnt < size; ++cnt) swap(a[cnt],b[cnt]); } void secret(char *l, char *r, size_t size,int (*compar)(const void*, const void*)) { char *j = r; char *i = l+size; while (i <= j) { if (compar(l,i) < 0) { swapsize(j, i, size); j -= size; } else { i += size; } } swapsize(l, j, size); j -= size; if (l < j) secret1(l, j, compar); if (i < r) secret1(i, r, compar); } void mqsort(void* base, size_t num, size_t size, int (*compar)(const void*, const void*)) { switch (size) { case 1: secret1((uint8_t*)base, (uint8_t*)base+(num-1), compar); break; case 2: secret1((uint16_t *)base, (uint16_t *)base+(num-1), compar); break; case 4: secret1((uint32_t *)base, (uint32_t*)base+(num-1), compar); break; case 8: secret1((uint64_t *)base, (uint64_t *)base+(num-1), compar); break; default: secret((char*)base, (char*)base+(num-1)*size, size, compar); } } template int compr(const void * a, const void * b){ T aa = *(T*)a; T bb = *(T*)b; if (aa > bb) return 1; if (aa < bb) return -1; return 0; } template void* genInt(size_t num) { std::random_device r; std::mt19937_64 e(r()); std::uniform_int_distribution unifrom_dist(0, 1 << (sizeof(T)*8 -2)); T * res = (T*)malloc(num * sizeof(T)); for (size_t i = 0; i void* genFloat(size_t num) { std::random_device r; std::mt19937_64 e(r()); std::uniform_real_distribution unifrom_dist(0, 1); T * res = (T*)malloc(num * sizeof(T)); for (size_t i = 0; i void* gen(size_t num) { return genInt(num); } template <> void* gen(size_t num) { return genFloat(num); } template <> void* gen(size_t num) { return genFloat(num); } int compeq(uint32_t *a,uint32_t *b, size_t size) { for (size_t i = 0; i< size; ++i) if (a[i] != b[i]) return 1; return 0; } template void print(void *v, size_t num) { T * k = (T*) v; for (int i = 0; i void runAndTest(size_t num) { clock_t tst; clock_t tmd; clock_t ted; size_t size = sizeof(T); void *base = gen(num); void *base2 = malloc(num*size); memcpy(base2,base,num*size); tst = clock(); mqsort(base,num,size,compr); tmd = clock(); qsort(base2,num,size,compr); ted = clock(); if (compeq((uint32_t*)base,(uint32_t*)base2,num*size/4)) { std::cout << "Not equal" << std::endl; print(base, num); print(base2,num); } else std::cout<<"Equal"< [TYPE] [LENGTH]" <(num); break; case 'l': runAndTest(num); break; case 'f': runAndTest(num); break; case 'd': runAndTest(num); break; default: usage(); return -1; } return 0; }