📄 multikeyqsort.cpp
字号:
/* Copyright 2007 Stefan Webb
This file is part of Burstsort.
Burstsort is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Burstsort is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Burstsort; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
// Code taken with permission from http://www.cs.princeton.edu/~rs/strings/demo.c by Robert Sedgewick.
#include "main.h"
#ifndef min
#define min(a, b) ((a)<=(b) ? (a) : (b))
#endif
//#define swap(a, b) { char *t=x[a]; \
//x[a]=x[b]; x[b]=t; }
#define swap2(a, b) { t = *(a); *(a) = *(b); *(b) = t; }
#define ptr2char(i) (*(*(i) + depth))
#define med3(a, b, c) med3func(a, b, c, depth)
void vecswap2(char **a, char **b, int n)
{ while (n-- > 0) {
char *t = *a;
*a++ = *b;
*b++ = t;
}
}
char **med3func(char **a, char **b, char **c, int depth)
{ int va, vb, vc;
if ((va=ptr2char(a)) == (vb=ptr2char(b)))
return a;
if ((vc=ptr2char(c)) == va || vc == vb)
return c;
return va < vb ?
(vb < vc ? b : (va < vc ? c : a ) )
: (vb > vc ? b : (va < vc ? a : c ) );
}
void inssort(char **a, int n, int d)
{ char **pi, **pj, *s, *t;
for (pi = a + 1; --n > 0; pi++)
for (pj = pi; pj > a; pj--) {
// Inline strcmp: break if *(pj-1) <= *pj
for (s=*(pj-1)+d, t=*pj+d; *s==*t && *s!=0; s++, t++)
;
if (*s <= *t)
break;
swap2(pj, pj-1);
}
}
void ssort2(char **a, int n, int depth)
{ int d, r, partval;
char **pa, **pb, **pc, **pd, **pl, **pm, **pn, *t;
if (n < 10) {
inssort(a, n, depth);
return;
}
pl = a;
pm = a + (n/2);
pn = a + (n-1);
if (n > 30) { // On big arrays, pseudomedian of 9
d = (n/8);
pl = med3(pl, pl+d, pl+2*d);
pm = med3(pm-d, pm, pm+d);
pn = med3(pn-2*d, pn-d, pn);
}
pm = med3(pl, pm, pn);
swap2(a, pm);
partval = ptr2char(a);
pa = pb = a + 1;
pc = pd = a + n-1;
for (;;) {
while (pb <= pc && (r = ptr2char(pb)-partval) <= 0) {
if (r == 0) { swap2(pa, pb); pa++; }
pb++;
}
while (pb <= pc && (r = ptr2char(pc)-partval) >= 0) {
if (r == 0) { swap2(pc, pd); pd--; }
pc--;
}
if (pb > pc) break;
swap2(pb, pc);
pb++;
pc--;
}
pn = a + n;
r = min(pa-a, pb-pa); vecswap2(a, pb-r, r);
r = min(pd-pc, pn-pd-1); vecswap2(pb, pn-r, r);
if ((r = pb-pa) > 1)
ssort2(a, r, depth);
if (ptr2char(a + r) != 0)
ssort2(a + r, pa-a + pn-pd-1, depth+1);
if ((r = pd-pc) > 1)
ssort2(a + n-r, r, depth);
}
void ssort2main(char **a, int n) { ssort2(a, n, 0); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -