#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); } }