[NonSerialized]
private static int[] LP = new int[] {
1, 1, 3, 5, 9, 15, 25, 41, 67, 109,
177, 287, 465, 753, 1219, 1973, 3193, 5167, 8361, 13529, 21891,
35421, 57313, 92735, 150049, 242785, 392835, 635621, 1028457,
1664079, 2692537, 4356617, 7049155, 11405773, 18454929, 29860703,
48315633, 78176337, 126491971, 204668309, 331160281, 535828591,
866988873 // the next number is > 31 bits.
};
private static void Sift(T[] m, int pshift, int head)
where T : IComparable
{
T val = m[head];
while (pshift > 1)
{
int rt = head - 1;
int lf = head - 1 - LP[pshift - 2];
if (val.CompareTo(m[lf]) >= 0 &&
val.CompareTo(m[rt]) >= 0)
break;
if (m[lf].CompareTo(m[rt]) >= 0)
{
m[head] = m[lf];
head = lf;
pshift -= 1;
}
else
{
m[head] = m[rt];
head = rt;
pshift -= 2;
}
}
m[head] = val;
}
[CLSCompliant(false)]
private static int NumberOfTrailingZeros(uint x)
{
int n = 32;
while (x != 0u)
{
n--;
x += x;
}
return n;
}
private static void Trinkle(T[] m, int p, int pshift, int head, bool isTrusty)
where T : IComparable
{
T val = m[head];
while (p != 1)
{
int stepson = head - LP[pshift];
if (m[stepson].CompareTo(val) <= 0)
break;
if (!isTrusty && pshift > 1)
{
int rt = head - 1;
int lf = head - 1 - LP[pshift - 2];
if (m[rt].CompareTo(m[stepson]) >= 0 ||
m[lf].CompareTo(m[stepson]) >= 0)
break;
}
m[head] = m[stepson];
head = stepson;
int trail = NumberOfTrailingZeros((uint)(p & ~1));
p >>= trail;
pshift += trail;
isTrusty = false;
}
if (!isTrusty)
{
m[head] = val;
Sift(m, pshift, head);
}
}
public static TimeSpan SmoothSort(T[] m, int lo, int hi)
where T : IComparable
{
DateTime start = DateTime.Now;
int head = lo;
int p = 1;
int pshift = 1;
while (head < hi)
{
if ((p & 3) == 3)
{
Sift(m, pshift, head);
p >>= 2;
pshift += 2;
}
else
{
if (LP[pshift - 1] >= hi - head)
Trinkle(m, p, pshift, head, false);
else
Sift(m, pshift, head);
if (pshift == 1)
{
p <<= 1;
pshift--;
}
else
{
p <<= (pshift - 1);
pshift = 1;
}
}
p |= 1;
head++;
}
Trinkle(m, p, pshift, head, false);
while (pshift != 1 || p != 1)
{
if (pshift <= 1)
{
int trail = NumberOfTrailingZeros((uint)(p & ~1));
p >>= trail;
pshift += trail;
}
else
{
p <<= 2;
p ^= 7;
pshift -= 2;
Trinkle(m, p >> 1, pshift + 1, head - LP[pshift] - 1, true);
Trinkle(m, p, pshift, head - 1, true);
}
head--;
}
return DateTime.Now - start;
}
public static TimeSpan SmoothSort(T[] items)
where T : IComparable
{
return SmoothSort(items, 0, items.Length - 1);
}