#include <iostream>
#include <iterator>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <cassert>
std::vector<int> generateIntList(int size = 10)
{
std::vector<int> result_list;
std::generate_n(
std::back_insert_iterator<std::vector<int>>(result_list),
size,
[]() { return std::rand() % 10; }
);
return std::move(result_list);
}
void showIntList(const std::vector<int>& ll)
{
//std::cout << "list: ";
std::copy(ll.begin(), ll.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n";
}
//插入排序
//每次遍历保证p位置的元素,比p左边的元素小
void insertSort(std::vector<int>& ll)
{
for (decltype(ll.size()) p = 1; p < ll.size(); ++p)
{
auto tmp = ll[p];
auto j = p;
for (; j > 0 && tmp < ll[j - 1]; --j)
{
ll[j] = ll[j - 1];
}
ll[j] = tmp;
}
}
void insertSort(std::vector<int>& ll, int left, int right)
{
for (decltype(ll.size()) p = left + 1; p <= right; ++p)
{
auto tmp = ll[p];
auto j = p;
for (; j > left && tmp < ll[j - 1]; --j)
{
ll[j] = ll[j - 1];
}
ll[j] = tmp;
}
}
//谢尔排序
//带增量的插入排序。。。
void shellSort(std::vector<int>& ll)
{
for (auto gap = ll.size() / 2; gap > 0; gap /= 2)
{
for (auto p = gap; p < ll.size(); p++)
{
auto tmp = ll[p];
auto j = p;
for (; j >= gap && tmp < ll[j - gap]; j -= gap)
{
ll[j] = ll[j - gap];
}
ll[j] = tmp;
}
}
}
//堆排序
//先建立二叉大顶堆,交换堆顶元素和最后一个元素
//二叉堆的性质:位置在i的元素,左儿子在2i,右儿子在2i+1
//将位置i的元素下滤到指定的层数, 每次都是与左右两个儿子中的较大值进行交换, 大于两个儿子时停止下滤
void percDown(std::vector<int>& ll, int i, int n)
{
auto leftChild = [](const int i) -> int {return 2 * i + 1; };
int child;
auto tmp = ll[i];
for (; leftChild(i) < n; i = child)
{
child = leftChild(i);
if (child != n - 1 && ll[child] < ll[child + 1])
{
++child;
}
if (tmp < ll[child])
{
ll[i] = ll[child];
}
else
{
break;
}
}
ll[i] = tmp;
}
void heapSort(std::vector<int>& ll)
{
//从下往上进行下滤操作,建立一个大顶堆
for (int i = ll.size() / 2; i >= 0; --i)
{
percDown(ll, i, ll.size());
}
for (int j = ll.size() - 1; j > 0; --j)
{
std::swap(ll[0], ll[j]);//交换堆顶元素和最后一个元素
percDown(ll, 0, j);//对堆顶进行下滤操作
}
}
//归并排序
void merg(std::vector<int>& ll, std::vector<int>& tmpArray, int leftPos, int rightPos, int rightEnd)
{
auto leftEnd = rightPos - 1;
auto tmpPos = leftPos;
auto numElements = rightEnd - leftPos + 1;
while (leftPos <= leftEnd && rightPos <= rightEnd)
{
if (ll[leftPos] <= ll[rightPos])
{
tmpArray[tmpPos++] = ll[leftPos++];
}
else
{
tmpArray[tmpPos++] = ll[rightPos++];
}
}
while (leftPos <= leftEnd)
{
tmpArray[tmpPos++] = ll[leftPos++];
}
while (rightPos <= rightEnd)
{
tmpArray[tmpPos++] = ll[rightPos++];
}
for (auto i = 0; i < numElements; i++, rightEnd--)
{
ll[rightEnd] = tmpArray[rightEnd];
}
}
//分治策略, 数组切成两半,然后对两个数组进行排序之后, 然后再合并
void mergSortDriver(std::vector<int>& ll, std::vector<int>& tmpArray, int left, int right)
{
if (left < right)
{
auto center = (left + right) / 2;
mergSortDriver(ll, tmpArray, left, center);
mergSortDriver(ll, tmpArray, center + 1, right);
merg(ll, tmpArray, left, center + 1, right);
}
}
void mergSort(std::vector<int>& ll)
{
std::vector<int> tmpArray(ll.size());
mergSortDriver(ll, tmpArray, 0, ll.size() - 1);
}
//快速排序
//选择一个枢纽元, 然后确保左边的元素小于枢纽元, 右边的元素大于枢纽元, 然后分别对左右两边分别进行快排
int median3(std::vector<int>& a, int left, int right)
{
auto center = (left + right) / 2;
if (a[center] < a[left])
{
std::swap(a[left], a[center]);
}
if (a[right] < a[left])
{
std::swap(a[left], a[right]);
}
if (a[right]<a[center])
{
std::swap(a[center], a[right]);
}
std::swap(a[center], a[right - 1]);
return a[right - 1];
}
void quickSort(std::vector<int>& ll, int left, int right)
{
if (left + 10 <= right)
{
auto pivot = median3(ll, left, right);
auto i = left, j = right - 1;
while (true)
{
while (ll[++i] < pivot) {}
while (pivot < ll[--j]) {}
if (i<j)
{
std::swap(ll[i], ll[j]);
}
else
{
break;
}
}
std::swap(ll[i], ll[right - 1]);
quickSort(ll, left, i - 1);
quickSort(ll, i + 1, right);
}
else
{
insertSort(ll, left, right);
}
}
void sort_test()
{
if (true)
{
auto l1 = generateIntList();
auto l2 = l1;
std::cout << "insertSort>>>>" << '\n';
std::cout << "before: ";
showIntList(l1);
insertSort(l1);
std::cout << "l1: ";
showIntList(l1);
std::sort(l2.begin(), l2.end());
std::cout << "l2: ";
showIntList(l2);
//用标准库的sort函数的结果来进行测试验证
assert(l1 == l2);
}
if (true)
{
auto l1 = generateIntList();
auto l2 = l1;
std::cout << "shellSort>>>>" << '\n';
std::cout << "before: ";
showIntList(l1);
shellSort(l1);
std::cout << "l1: ";
showIntList(l1);
std::sort(l2.begin(), l2.end());
std::cout << "l2: ";
showIntList(l2);
//用标准库的sort函数的结果来进行测试验证
assert(l1 == l2);
}
if (true)
{
auto l1 = generateIntList();
auto l2 = l1;
std::cout << "heapSort>>>>" << '\n';
std::cout << "before: ";
showIntList(l1);
heapSort(l1);
std::cout << "l1: ";
showIntList(l1);
std::sort(l2.begin(), l2.end());
std::cout << "l2: ";
showIntList(l2);
//用标准库的sort函数的结果来进行测试验证
assert(l1 == l2);
}
if (true)
{
auto l1 = generateIntList();
auto l2 = l1;
std::cout << "mergSort>>>>" << '\n';
std::cout << "before: ";
showIntList(l1);
mergSort(l1);
std::cout << "l1: ";
showIntList(l1);
std::sort(l2.begin(), l2.end());
std::cout << "l2: ";
showIntList(l2);
//用标准库的sort函数的结果来进行测试验证
assert(l1 == l2);
}
if (true)
{
auto l1 = generateIntList(30);
auto l2 = l1;
std::cout << "quickSort>>>>" << '\n';
std::cout << "before: ";
showIntList(l1);
quickSort(l1, 0, l1.size() - 1);
std::cout << "l1: ";
showIntList(l1);
std::sort(l2.begin(), l2.end());
std::cout << "l2: ";
showIntList(l2);
//用标准库的sort函数的结果来进行测试验证
assert(l1 == l2);
}
}