9
//___________________________________________________________________________
10
// check if every element is zero
11
inline bool check_zero(int *mem, int n) {
12
for(int *v = mem+n; v!=mem; ) if(*(--v)!=0) return false;
16
//___________________________________________________________________________
17
// Sort simple integer arrays in ASCENDING order
18
//___________________________________________________________________________
19
inline int med3(int a, int b, int c) {
21
if(c<b) return (a<c) ? c : a;
25
if(c<a) return (b<c) ? c : b;
30
inline void isort(int *v, int t) {
32
for(int i=1; i<t; i++) {
33
register int *w = v+i;
35
while(w!=v && *(w-1)>tmp) { *w = *(w-1); w--; }
40
inline int partitionne(int *v, int t, int p) {
44
while(i<=j && v[i]<p) i++;
45
while(i<=j && v[j]>p) j--;
52
if(i==j && v[i]<p) i++;
57
inline void qsort(int *v, int t) {
60
int x = partitionne(v, t, med3(v[t>>1], v[(t>>2)+2], v[t-(t>>1)-2]));
66
inline int qsort_median(int *v, int t, int pos) {
67
if(t<10) { isort(v,t); return v[pos]; }
68
int x = partitionne(v, t, med3(v[t>>1], v[(t>>2)+2], v[t-(t>>1)-2]));
69
if(pos<x) return qsort_median(v, x, pos);
70
else return qsort_median(v+x, t-x, pos-x);
73
inline int qsort_median(int *v, int t) { return qsort_median(v,t,t/2); }
75
//___________________________________________________________________________
76
// Sort simple double arrays in ASCENDING order
77
//___________________________________________________________________________
78
inline double med3(double a, double b, double c) {
80
if(c<b) return (a<c) ? c : a;
84
if(c<a) return (b<c) ? c : b;
89
inline void isort(double *v, int t) {
91
for(int i=1; i<t; i++) {
92
register double *w = v+i;
94
while(w!=v && *(w-1)>tmp) { *w = *(w-1); w--; }
99
inline int partitionne(double *v, int t, double p) {
103
while(i<=j && v[i]<p) i++;
104
while(i<=j && v[j]>p) j--;
111
if(i==j && v[i]<p) i++;
112
assert(i!=0 && i!=t);
116
inline void qsort(double *v, int t) {
119
int x = partitionne(v, t, med3(v[t>>1], v[(t>>2)+2], v[t-(t>>1)-2]));
125
inline double qsort_median(double *v, int t, int pos) {
126
if(t<10) { isort(v,t); return v[pos]; }
127
int x = partitionne(v, t, med3(v[t>>1], v[(t>>2)+2], v[t-(t>>1)-2]));
128
if(pos<x) return qsort_median(v, x, pos);
129
else return qsort_median(v+x, t-x, pos-x);
132
inline double qsort_median(double *v, int t) { return qsort_median(v,t,t/2); }
134
//___________________________________________________________________________
135
// Sort integer arrays according to value stored in mem[], in ASCENDING order
136
inline void isort(int *mem, int *v, int t) {
138
for(int i=1; i<t; i++) {
142
for(j=i; j>0 && tmp<mem[v[j-1]]; j--) v[j]=v[j-1];
147
inline void qsort(int *mem, int *v, int t) {
148
if(t<15) isort(mem,v,t);
150
int p = med3(mem[v[t>>1]], mem[v[(t>>2)+3]], mem[v[t-(t>>1)-3]]);
154
while(i<=j && mem[v[i]]<p) i++;
155
while(i<=j && mem[v[j]]>p) j--;
162
if(i==j && mem[v[i]]<p) i++;
163
assert(i!=0 && i!=t);
169
//Box-Sort 1..n according to value stored in mem[], in DESCENDING order.
170
inline int *pre_boxsort(int *mem, int n, int &offset) {
172
// maximum and minimum
175
for(yo=mem+n-1; yo!=mem; yo--) {
176
register int x = *yo;
182
int *box = new int[c];
183
for(yo=box+c; yo!=box; *(--yo)=0);
184
for(yo=mem+n; yo!=mem; box[*(--yo)-mn]++);
187
for(yo=box+c; yo!=box; ) {
195
inline int *boxsort(int *mem, int n, int *buff=NULL) {
197
if(n<=0) return buff;
199
int *box = pre_boxsort(mem,n,offset);
201
if(buff==NULL) buff=new int[n];
202
for(i=0; i<n; i++) buff[--box[mem[i]-offset]]=i;
208
// merge two sorted arays in their intersection. Store the result in first array, and return length
209
inline int intersect(int *a, int a_len, int *b, int b_len) {
210
if(a_len==0 || b_len==0) return 0;
216
if (*a == *b) p[len++] = *a;
217
do if(++a == asup) return len; while(*a<*b);
218
if (*a == *b) p[len++] = *a;
219
do if(++b == bsup) return len; while(*b<*a);
223
// merge two sorted arays in their union, store result in m
224
inline int unify(int *m, int *a, int a_len, int *b, int b_len) {
228
while(a!=asup && b!=bsup) {
229
if(*a < *b) m[len++] = *(a++);
235
while(a!=asup) m[len++]=*(a++);
236
while(b!=asup) m[len++]=*(b++);
240
// lexicographic compare
241
inline int lex_comp(int *v1, int *v2, int n) {
243
while(v1!=stop && *v1==*v2) { v1++; v2++; };
244
if(v1==stop) return 0; else if(*v1<*v2) return -1; else return 1;
246
// lexicographic median of three
247
inline int *lex_med3(int *a, int *b, int *c, int s) {
248
int ab = lex_comp(a,b,s);
251
int cb = lex_comp(c,b,s);
253
int ca = lex_comp(c,a,s);
254
if(ab<0) { if(cb>0) return b; else return (ca>0) ? c : a; }
255
else { if(cb<0) return b; else return (ca<0) ? c : a; }
259
// Lexicographic sort
260
inline void lex_isort(int **l, int *v, int t, int s) {
262
for(int i=1; i<t; i++) {
263
register int *w = v+i;
265
while(w!=v && lex_comp(l[tmp],l[*(w-1)],s)<0) { *w = *(w-1); w--; }
270
#ifdef _STABLE_SORT_ONLY
271
#define _CRITICAL_SIZE_QSORT 0x7FFFFFFF
272
#warning "lex_qsort will be replaced by lex_isort"
274
#define _CRITICAL_SIZE_QSORT 15
277
inline void lex_qsort(int **l, int *v, int t, int s) {
279
if(t<_CRITICAL_SIZE_QSORT) lex_isort(l,v,t,s);
281
int *p = lex_med3(l[v[t>>1]], l[v[(t>>2)+2]], l[v[t-(t>>1)-2]], s);
284
// printf("pivot = %d\n",p);
286
// for(int k=0; k<t; k++) printf("%d ",v[k]);
287
while(i<=j && lex_comp(l[v[i]],p,s)<0) i++;
288
while(i<=j && lex_comp(l[v[j]],p,s)>0) j--;
290
// printf(" swap %d[%d] with %d[%d]\n",i,v[i],j,v[j]);
296
if(i==j && lex_comp(l[v[i]],p,s)<0) i++;
297
assert(i!=0 && i!=t);
299
lex_qsort(l,v+i,t-i,s);
303
// lexicographic indirect compare
304
inline int lex_comp_indirect(int *key, int *v1, int *v2, int n) {
306
while(v1!=stop && key[*v1]==key[*v2]) { v1++; v2++; };
307
if(v1==stop) return 0; else if(key[*v1]<key[*v2]) return -1; else return 1;
310
inline int qsort_min(const int a, const int b) { return a<=b ? a : b; }
312
// mix indirect compare
313
inline int mix_comp_indirect(int *key, int a, int b, int **neigh, int *degs)
315
if(key[a]<key[b]) return -1;
316
else if(key[a]>key[b]) return 1;
318
int cmp=lex_comp_indirect(key,neigh[a],neigh[b],qsort_min(degs[a],degs[b]));
320
if(degs[a]>degs[b]) return -1;
321
if(degs[a]<degs[b]) return 1;
326
// lexicographic indirect median of three
327
inline int mix_med3_indirect(int *key, int a, int b, int c, int **neigh, int *degs) {
328
int ab = mix_comp_indirect(key,a,b,neigh,degs);
331
int cb = mix_comp_indirect(key,c,b,neigh,degs);
333
int ca = mix_comp_indirect(key,c,a,neigh,degs);
334
if(ab<0) { if(cb>0) return b; else return (ca>0) ? c : a; }
335
else { if(cb<0) return b; else return (ca<0) ? c : a; }
339
// Sort integer arrays in ASCENDING order
340
inline void mix_isort_indirect(int *key, int *v, int t, int **neigh, int *degs)
343
for(int i=1; i<t; i++) {
344
register int *w = v+i;
346
while(w!=v && mix_comp_indirect(key,tmp,*(w-1),neigh,degs)<0) {
354
inline void mix_qsort_indirect(int *key, int *v, int t, int **neigh, int *degs)
356
if(t<15) mix_isort_indirect(key,v,t,neigh,degs);
358
int p = mix_med3_indirect(key, v[t>>1], v[(t>>2)+2], v[t-(t>>1)-2], neigh, degs);
361
// printf("pivot = %d\n",p);
363
// for(int k=0; k<t; k++) printf("%d ",v[k]);
364
while(i<=j && mix_comp_indirect(key,v[i],p,neigh,degs)<0) i++;
365
while(i<=j && mix_comp_indirect(key,v[j],p,neigh,degs)>0) j--;
367
// printf(" swap %d[%d] with %d[%d]\n",i,v[i],j,v[j]);
373
if(i==j && mix_comp_indirect(key,v[i],p,neigh,degs)<0) i++;
374
assert(i!=0 && i!=t);
375
mix_qsort_indirect(key,v,i,neigh,degs);
376
mix_qsort_indirect(key,v+i,t-i,neigh,degs);
380
} // namespace gengraph