归并排序和快速排序,在小数组的时候,使用插入排序,在10个左右的数据时候,插入排序表现更好,也防止多次递归。
快速排序使用了乱序函数。
注明:没有使用模板函数,可以自行添加,这个只是传递排序思想。
#include <iostream>
#include <random>
#include <random>
#include <cstdlib>
#include <ctime>
#include <chrono>
#include <algorithm>
using namespace std;
using std::chrono::system_clock;
#define MAXSIZE 10000000
class my_sort
{
public:
void insert_sort(int a[], int len)//插入排序
{
for (int i = 1; i < len; i++)
{
for (int j = i; j > 0 && less(a[j], a[j - 1]); j--)
exch(a, j, j - 1);
}
}
void insert_sort(int a[], int begin, int end)//插入排序
{
int len = end - begin + 1;
for (int i = begin; i < len; i++)
{
for (int j = i; j > 0 && less(a[j], a[j - 1]); j--)
exch(a, j, j - 1);
}
}
void xr_sort(int a[], int len)//希尔排序
{
int h = 1;
while (h < len / 3)
h = 3 * h + 1;
while (h >= 1)//这里必须是大于等于,不然会导致排序出错,可能h = 2就退出
{
for (int i = 0; i < len; i++)
{
for (int j = i; j >= h && less(a[j], a[j - h]); j -= h)
exch(a, j, j - h);
}
h /= 3;
}
}
void sel_sort(int a[], int len)//选择排序
{
for (int i = 0; i < len; i++)
{
int min = i;
for (int j = i+1; j < len; j++)
if (less(a[j], a[min]))
min = j;
exch(a, i, min);
}
}
void gb_sort(int a[], int len)//归并排序
{
//gb_sort(a, 0, len - 1)
_updata_gb_sort(a, 0, len - 1);
}
void fast_sort(int a[], int len)//快速排序
{
random_shuffle(a, &a[len - 1]);//随机
fast_sort(a, 0, len - 1);
}
private:
int less(int i, int m)
{
return i < m;
}
void exch(int a[], int i, int j)
{
int n = a[i];
a[i] = a[j];
a[j] = n;
}
void merge(int a[], int begin, int mid, int end)
{
int *aux = new int[end - begin + 1];
for (int i = begin; i <= end; i++)
{
aux[i - begin] = a[i];
}
int k1 = begin, k2 = mid + 1;
for (int i = begin; i <= end; i++)
{
if (k1 > mid)
{
a[i] = aux[k2 - begin];
k2++;
}
else if (k2 > end)
{
a[i] = aux[k1 - begin];
k1++;
}
else if(less(aux[k1 - begin], aux[k2 - begin]))
{
a[i] = aux[k1 - begin];
k1++;
}
else
{
a[i] = aux[k2 - begin];
k2++;
}
}
delete[]aux;
}
void gb_sort(int a[], int begin, int end)
{
if (begin >= end)
return;
else
{
int mid = (begin + end) / 2;
gb_sort(a, begin, mid);
gb_sort(a, mid + 1, end);
merge(a, begin, mid, end);
}
}
void _updata_gb_sort(int a[], int begin, int end)
{
if (begin + 10 >= end)//在小数组时候,调整成插入排序,更加节省时间
{
insert_sort(a, begin, end);
}
else
{
int mid = (begin + end) / 2;
gb_sort(a, begin, mid);
gb_sort(a, mid + 1, end);
merge(a, begin, mid, end);
}
}
void fast_sort(int a[], int begin, int end)
{
if (begin + 10 >= end)
insert_sort(a, begin, end);
else
{
int mid = find_mid(a, begin, end);
fast_sort(a, begin, mid - 1);//这里必须是mid-1, 如果是mid的话,会导致end永远为2,陷入死循环
fast_sort(a, mid + 1, end);
}
}
int find_mid(int a[], int begin, int end)
{
int value = a[begin];
int i = begin, j = end + 1;
while (true)
{
while (less(a[++i], value)) if (i == end) break;
while (less(value, a[--j])) if (j == begin) break;
if (i >= j) break;
exch(a, i, j);
}
exch(a, j, begin);
return j;
}
};
template<typename T>
int get_len(T &array)
{
return (sizeof(array) / sizeof(array[0]));
}
int a[MAXSIZE];
int b[MAXSIZE];
int c[MAXSIZE];
int d[MAXSIZE];
int e[MAXSIZE];
int main()
{
my_sort test;
srand(time(0));
for (int i = 0; i < MAXSIZE; i++)
{
a[i] = rand() % 10000000;
b[i] = a[i];
c[i] = a[i];
d[i] = a[i];
e[i] = a[i];
}
cout << 1 << endl;
system_clock::time_point big, end;
big = system_clock::now();
test.fast_sort(a, MAXSIZE);
end = system_clock::now();
cout << "快速排序时间:" << system_clock::to_time_t(end) - system_clock::to_time_t(big) << endl;
big = system_clock::now();
test.gb_sort(b, MAXSIZE);
end = system_clock::now();
cout << "归并排序时间:" << system_clock::to_time_t(end) - system_clock::to_time_t(big) << endl;
big = system_clock::now();
std::sort(c, &c[MAXSIZE]);
end = system_clock::now();
cout << "系统排序时间:" << system_clock::to_time_t(end) - system_clock::to_time_t(big) << endl;
big = system_clock::now();
test.xr_sort(d, MAXSIZE);
end = system_clock::now();
cout << "希尔排序时间:" << system_clock::to_time_t(end) - system_clock::to_time_t(big) << endl;
/*big = system_clock::now();
test.sel_sort(a, get_len(d));
end = system_clock::now();
cout << "选择排序时间:" << system_clock::to_time_t(end) - system_clock::to_time_t(big) << endl;*/
for (int i = 9000000; i < 9000100; i++)
{
cout << a[i]<< " " << b[i] << " "<< c[i] <<" " << d[i] << " " << e[i] << endl;
}
return 0;
}