头文件
#ifndef __SORint__
#define __SORint__
#include<vector>
//生成随机数
void randVec(int n, std::vector<int>& a, int max, int min);//生成n个随机数,添加到数组a中,max与min表示随机数范围
//插入排序
void insertSort(std::vector<int>& );//插入排序
void insertSort(std::vector<int>&elems,int left,int right);//插入排序
//希尔排序
void shellSort(std::vector<int>&);//使用希尔增量的希尔排序
//归并排序
void mergeSort(std::vector<int>&);//归并排序用户方法,归并排序由内部方法实现
void mergeSort(std::vector<int>& elems, std::vector<int>& temArray, int left, int right);//归并排序的内部方法
void merge(std::vector<int>& elems, std::vector<int>& temArray, int leftPos, int rightPos, int rightEnd);//合并经过归并排序后的数组
//三数中值分割法快速排序
void quickSort(std::vector<int>& elems);//快速排序用户方法
void quickSort(std::vector<int>& elems, int left, int right);//快速排序内部方法
int midOf3(std::vector<int>& elems, int left, int right);//执行三数中值分割的函数
//课本上的选择第一个元素作为枢纽的快速排序
void textQuickSort(std::vector<int>&elems);
void textQuickSort(std::vector<int>& elems, int left, int right);
#endif
cpp
#include<random>
#include<iomanip>
#include "Sort.h"
void randVec(int n, std::vector<int>& a, int min, int max) {//生成n个随机数,添加到数组a中,max与min表示随机数范围
std::uniform_int_distribution<int> u(min, max);
std::default_random_engine e(time(0));
for (int i = 0; i < n; ++i)
a.push_back(u(e));
}
//插入排序
void insertSort(std::vector<int>& elems) {
insertSort(elems, 0, elems.size() - 1);
}
void insertSort(std::vector<int>& elems, int left, int right) {
int tem = elems[left];
for (int i = left + 1; i <= right; ++i) {
tem = std::move(elems[i]);
int j = 0;
for (j = i; j > left && tem < elems[j - 1]; --j) {
elems[j] = std::move(elems[j - 1]);
}
elems[j] = std::move(tem);
}
}
//希尔排序
void shellSort(std::vector<int>& elems) {//使用希尔增量的希尔排序
for (int gap = elems.size() / 2; gap > 0; gap /= 2) {
for (int i = 0; i < gap; ++i) {
int tem = 0;
int cur = 0;
for (int j = i; j < elems.size(); j += gap) {
tem = std::move(elems[j]);
cur = j;
while (cur > i && tem < elems[cur - gap]) {
elems[cur] = std::move(elems[cur - gap]);
cur -= gap;
}
elems[cur] = std::move(tem);
}
}
}
}
//归并排序
void mergeSort(std::vector<int>& elems) {
std::vector<int> temArray(elems.size());//创建一个等大的数组用来存储排序后的结果
mergeSort(elems, temArray, 0, elems.size());//调用内部归并排序方法
}
void mergeSort(std::vector<int>& elems, std::vector<int>& temArray, int left, int right) {
if (left == right)
return;
int mid = left + (right - left) / 2;//mid可能等于left,不可能等于right,left==right-1时mid等于left
mergeSort(elems, temArray, left, mid);//所以此处设置左半部分为left到mid,而不能是left到mid-1
mergeSort(elems, temArray, mid + 1, right);
merge(elems, temArray, left, mid + 1, right);//归并拍完序的两部分
}
void merge(std::vector<int>& elems, std::vector<int>& temArray, int leftPos, int rightPos, int rightEnd) {
int lpos = leftPos, lend = rightPos - 1;
int rpos = rightPos, rend = rightEnd;
int tpos = leftPos;//向tamArray中写入的指针
while (lpos <= lend && rpos <= rend) {
if (elems[lpos] < elems[rpos]) {
temArray[tpos++] = std::move(elems[lpos++]);
}
else {
temArray[tpos++] = std::move(elems[rpos++]);
}
while (lpos <= lend) {
temArray[tpos++] = std::move(elems[lpos++]);
}
while (rpos <= rend) {
temArray[tpos++] = std::move(elems[rpos++]);
}
for (tpos = leftPos; tpos <= rightEnd; ++tpos) {
elems[tpos] = std::move(temArray[tpos]);//将元素移动回去,这一步恢复是前面的move操作的依据
}
}
}
//三数中值分割法快速排序
void quickSort(std::vector<int>& elems) {
quickSort(elems, 0, elems.size() - 1);
}
void quickSort(std::vector<int>& elems, int left, int right) {
if (left + 10 <= right) {//对于小数组,快速排序不如插入排序,此处选择N=10,也能保证三数中值法能顺利实现
const int& pivot = midOf3(elems, left, right);//三数中值分割,获得枢纽元的值,此时枢纽元在elems[right-1]
int i = left;
int j = right - 1;
for (;;) {
while (elems[++i] < pivot) {}//找到第一个大于等于枢纽元的元素
while (pivot < elems[--j]) {}//第一个小于等于枢纽元的元素
if (i < j)
std::swap(elems[i], elems[j]);//交换
else
break;//此次分割结束
}
std::swap(elems[i], elems[right - 1]);//将枢纽元放在中间
quickSort(elems, left, i - 1);//递归分割左半部分
quickSort(elems, i + 1, right);//递归分割右半部分
}
else
insertSort(elems, left, right);//对小数组进行插入排序
}
int midOf3(std::vector<int>& elems, int left, int right) {
int mid = left + (right - left) / 2;
if (elems[mid] < elems[left])
std::swap(elems[mid], elems[left]);
if (elems[right] < elems[mid])
std::swap(elems[mid], elems[right]);
if (elems[right] < elems[left])
std::swap(elems[left], elems[right]);
std::swap(elems[mid], elems[right - 1]);//将枢纽元置于right-1处
return elems[right - 1];//返回枢纽元的值
}
//课本上的选择第一个元素作为枢纽的快速排序
void textQuickSort(std::vector<int>& elems) {
textQuickSort(elems, 0, elems.size() - 1);
}
void textQuickSort(std::vector<int>& elems, int left, int right) {
if (left >= right)
return;
int pivot = elems[left];
int l = left;
int r = right;
while (l < r) {
while (l < r && elems[r] >= pivot)
--r;
if (l < r)
elems[l++] = elems[r];
while (l < r && elems[l] < pivot)
++l;
if (l < r)
elems[r--] = elems[l];
}
elems[l] = pivot;
textQuickSort(elems, left, l - 1);
textQuickSort(elems, l + 1, right);
}