template<typename T>
void Sort(T* arr, int len, bool(*cmp)(T a, T b))
{
if (len < 250 || len % 50) {
int b = max(len / 50, 5);
int len2 = b * 50;
T m = GetMax(arr, len);
T* p = new T[len2];
for (int i = 0; i < len; i++)p[i] = arr[i];
for (int i = len; i < len2; i++)p[i] = m;
Sort(p, len2, cmp);
for (int i = 0; i < len; i++)arr[i] = p[i];
return;
}
const int s = 5;
int r = len / s; //r行s列
T* p = new T[len];
for (int i = 0; i < len; i += r)Sort2(arr + i, r, cmp);//每一列排序
for (int i = 0; i < len; i++) p[i / s + i % s * r] = arr[i];//转置
for (int i = 0; i < len; i += r)Sort2(p + i, r, cmp);//每一列排序
for (int i = 0; i < len; i++) arr[i] = p[i / s + i % s * r];//逆转置
for (int i = 0; i < len; i += r)Sort2(arr + i, r, cmp);//每一列排序
for (int i = r / 2; i < len - r; i += r)Sort2(arr + i, r, cmp);//最后一次排序
}
template<typename T>
bool cmp2(T a, T b, int dir)
{
if (dir == 0)return cmp(a, b);
else return cmp(b, a);
}
template<typename T>
void Sort(T* arr, int len, bool(*cmp)(T a, T b), int dir) // dir: 0 默认cmp 1 相反顺序
{
if (len <= 1)return;
Sort(arr, len / 2, cmp, dir);
Sort(arr + len / 2, len / 2, cmp, 1 - dir);
for (int k = 1; k < len; k *= 2) {
int d = len / k;
for (int s = 0; s < len; s += d) {
for (int i = s; i < s + d / 2; i++)
if (cmp2(arr[i + d / 2], arr[i], dir))exchange(arr + i + d / 2, arr + i);
}
}
}
template<typename T>
void Sort(T* arr, int len, bool(*cmp)(T a, T b))
{
int maxLen = 1;
while (maxLen < len)maxLen *= 2;
T* arr2 = new T[maxLen];
T m = GetMax(arr, len);
for (int i = 0; i < len; i++)arr2[i] = arr[i];
for (int i = len; i < maxLen; i++)arr2[i] = m;
Sort(arr2, maxLen, cmp, 0);
for (int i = 0; i < len; i++)arr[i] = arr2[i];
delete[]arr2;
}
3,等价形式
相当于把上面的网络的左下部分翻转一下,经过递归就得到方向一致的网络。
实现:
template<typename T>
void Sort2(T* arr, int len, bool(*cmp)(T a, T b))
{
if (len <= 1)return;
Sort2(arr, len / 2, cmp);
Sort2(arr + len / 2, len / 2, cmp);
for (int i = 0, j = len - 1; i < j; i++, j--) {
if (cmp(arr[j], arr[i]))exchange(arr + j, arr + i);
}
for (int k = 2; k < len; k *= 2) {
int d = len / k;
for (int s = 0; s < len; s += d) {
for (int i = s; i < s + d / 2; i++)
if (cmp(arr[i + d / 2], arr[i]))exchange(arr + i + d / 2, arr + i);
}
}
}
template<typename T>
void Sort(T* arr, int len, bool(*cmp)(T a, T b))
{
int maxLen = 1;
while (maxLen < len)maxLen *= 2;
T* arr2 = new T[maxLen];
T m = GetMax(arr, len);
for (int i = 0; i < len; i++)arr2[i] = arr[i];
for (int i = len; i < maxLen; i++)arr2[i] = m;
Sort2(arr2, maxLen, cmp);
for (int i = 0; i < len; i++)arr[i] = arr2[i];
delete[]arr2;
}
template<typename T>
void Merge(T* arr, int len, int d, bool(*cmp)(T a, T b))
{
if (d >= len / 2) {
if (cmp(arr[d], arr[0]))exchange(arr + d, arr);
return;
}
Merge(arr, len, d * 2, cmp);
Merge(arr + d, len - d, d * 2, cmp);
for (int i = d; i < len - d; i += d * 2) {
if (cmp(arr[i + d], arr[i]))exchange(arr + i + d, arr + i);
}
}
template<typename T>
void Sort2(T* arr, int len, bool(*cmp)(T a, T b))
{
if (len <= 1)return;
Sort2(arr, len / 2, cmp);
Sort2(arr + len / 2, len / 2, cmp);
Merge(arr, len, 1, cmp);
}