void vecswap(int i, int j, int n, Uint *x) { while(n-- > 0) { SWAPUINT(x, i, j); i++; j++; } }
Uint * quickSortMultikey (void *space, void* toSort, Uint size, Uint (*cmp)(Uint, Uint, Uint, void *, void*), Uint sentinel, void *info) { Sint a, b, c, d, v, n, r; Uint *sorted = NULL, offset; Uint depth = 0; Stack stack; if (size == 0) return NULL; sorted = ALLOCMEMORY(space, NULL, Uint, size); if (size<=1) { sorted[0]=0; } for (r=0; r < size; r++) sorted[r]=r; initStack(space, &stack, 100); n = size; offset=0; while (1) { a = rand() % n; SWAPUINT(sorted, offset, a+offset); v = sorted[offset]; a = b = 1; c = d = n-1; for(;;) { while(b<=c&&((r=cmp(sorted[b+offset],v,depth,toSort,info))==2||r==0)) { if (r==0) { SWAPUINT(sorted, a+offset, b+offset); a++; } b++; } while(b<=c&&((r=cmp(sorted[c+offset],v,depth,toSort,info))==1||r==0)) { if (r==0) { SWAPUINT(sorted, c+offset, d+offset); d--; } c--; } if (b > c) break; SWAPUINT(sorted, b+offset, c+offset); b++; c--; } r = MIN(a, (b-a)); vecswap(offset, (b-r)+offset, r, sorted); r = MIN((d-c), (n-d-1)); vecswap(b+offset, (n-r)+offset, r, sorted); /*sort lesser*/ r = b-a; if (r > 1) { stackpush(space, &stack, offset); stackpush(space, &stack, r); stackpush(space, &stack, depth); } /*sort equal*/ if ((a+n-d-1) > 1 && cmp(sorted[r+offset], sentinel, depth, toSort, info) != 0) /*if (r > 1 && sorted[r+offset]!=sentinel)*/ { stackpush(space, &stack, r+offset); stackpush(space, &stack, (a+n-d-1)); stackpush(space, &stack, depth+1); } /*sort greater*/ r=d-c; if (r > 1) { stackpush(space, &stack, (n-r)+offset); stackpush(space, &stack, r); stackpush(space, &stack, depth); } if (!stackisempty(&stack)) { depth = stackpop(&stack); n = stackpop(&stack); offset = stackpop(&stack); } else { break; } } destructStack(space, &stack); return sorted; }
Uint * quickSortMultikey (void *space, void* toSort, Uint size, Uint (*cmp)(Uint, Uint, Uint, void *, void*), Uint sentinel, void *info) { Sint a, b, c, d, v, n, r; TripleSint ins; Uint *sorted = NULL, offset; Uint depth = 0; VStack vstack; if (size == 0) return NULL; sorted = ALLOCMEMORY(space, NULL, Uint, size); if (size<=1) { sorted[0]=0; } for (r=0; r < size; r++) sorted[r]=r; bl_vstackInit(&vstack, 100, sizeof(TripleSint)); n = size; offset=0; while (1) { a = rand() % n; SWAPUINT(sorted, offset, a+offset); v = sorted[offset]; a = b = 1; c = d = n-1; for(;;) { while(b<=c&&((r=cmp(sorted[b+offset],v,depth,toSort,info))==2||r==0)) { if (r==0) { SWAPUINT(sorted, a+offset, b+offset); a++; } b++; } while(b<=c&&((r=cmp(sorted[c+offset],v,depth,toSort,info))==1||r==0)) { if (r==0) { SWAPUINT(sorted, c+offset, d+offset); d--; } c--; } if (b > c) break; SWAPUINT(sorted, b+offset, c+offset); b++; c--; } r = MIN(a, (b-a)); vecswap(offset, (b-r)+offset, r, sorted); r = MIN((d-c), (n-d-1)); vecswap(b+offset, (n-r)+offset, r, sorted); /*sort lesser*/ r = b-a; if (r > 1) { ins.a = offset; ins.b = r; ins.c = depth; bl_vstackPush(&vstack, &ins); } /*sort equal*/ if ((a+n-d-1) > 1 && cmp(sorted[r+offset], sentinel, depth, toSort, info) != 0) /*if (r > 1 && sorted[r+offset]!=sentinel)*/ { ins.a = r+offset; ins.b = (a+n-d-1); ins.c = depth+1; bl_vstackPush(&vstack, &ins); } /*sort greater*/ r=d-c; if (r > 1) { ins.a = (n-r)+offset; ins.b = r; ins.c = depth; bl_vstackPush(&vstack, &ins); } if (!bl_vstackIsEmpty(&vstack)){ ins = *((TripleSint *) bl_vstackPop(&vstack, NULL)); offset = ins.a; r = ins.b; depth = ins.c; } else { break; } } bl_vstackDestruct(&vstack, NULL); return sorted; }